summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2014-07-12 22:56:41 +0000
committerrpaulo <rpaulo@FreeBSD.org>2014-07-12 22:56:41 +0000
commit0cff4b03ddab4866935fdab21800c42ee8c1c6b2 (patch)
tree2f675ec37e93f585d83885a3063b6f30cdb74531 /cddl
parent196ba30fc44615a6eee4374b37450a4841abe010 (diff)
downloadFreeBSD-src-0cff4b03ddab4866935fdab21800c42ee8c1c6b2.zip
FreeBSD-src-0cff4b03ddab4866935fdab21800c42ee8c1c6b2.tar.gz
MFC 267929, 267937, 267939, 267940, 267941, 267942, 267987, 268006:
2915 DTrace in a zone should see "cpu", "curpsinfo", et al 2916 DTrace in a zone should be able to access fds[] 2917 DTrace in a zone should have limited provider access 4477 DTrace should speak JSON Add stubs for CTF functions which are not yet implemented. 4474 DTrace Userland CTF Support 4475 DTrace userland Keyword 4476 DTrace tests should be better citizens 4479 pid provider types 4480 dof emulation is missing checks 4471 DTrace count() with histogram 4472 DTrace full width distribution histograms 4473 DTrace frequency trails
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.c8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d32
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d.out646
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d.out38
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d53
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d.out124
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh75
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh.out102
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d43
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d.out149
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d35
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d.out211
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d179
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d.out218
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d51
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d.out13
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.c61
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d65
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d.out11
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/usdt.d27
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.fds.ksh91
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.func_access.ksh9
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.getf.ksh98
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.procpriv.ksh138
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.providers.ksh126
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d35
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d34
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d66
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out20
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d21
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d21
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d21
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh34
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh35
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh90
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c46
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c79
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh76
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.c29
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh45
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh44
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.c72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh69
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out16
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh70
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh83
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out4
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh72
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out4
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_open.c88
-rw-r--r--cddl/contrib/opensolaris/common/ctf/ctf_types.c41
-rw-r--r--cddl/contrib/opensolaris/common/util/strtolctype.h79
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c264
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c8
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c25
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c447
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c10
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h7
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c10
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c3
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y8
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c21
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h19
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l15
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c284
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h10
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c21
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c22
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c155
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h8
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c172
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h8
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c27
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c6
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c29
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c13
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h16
-rw-r--r--cddl/lib/libdtrace/libproc_compat.h2
84 files changed, 5580 insertions, 164 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
index a745ceb..4cbb866 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
@@ -25,6 +25,7 @@
*/
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -513,6 +514,7 @@ static void
print_probe_info(const dtrace_probeinfo_t *p)
{
char buf[BUFSIZ];
+ char *user;
int i;
oprintf("\n\tProbe Description Attributes\n");
@@ -536,10 +538,14 @@ print_probe_info(const dtrace_probeinfo_t *p)
oprintf("\n\tArgument Types\n");
for (i = 0; i < p->dtp_argc; i++) {
+ if (p->dtp_argv[i].dtt_flags & DTT_FL_USER)
+ user = "userland ";
+ else
+ user = "";
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);
+ oprintf("\t\targs[%d]: %s%s\n", i, user, buf);
}
if (p->dtp_argc == 0)
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d
new file mode 100644
index 0000000..a594afc
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d
@@ -0,0 +1,32 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+#pragma D option encoding=utf8
+#pragma D option aggzoom
+
+tick-1ms
+/i++ < 320/
+{
+ @ = lquantize(i, 0, 640, 1, i);
+ @ = lquantize(641 - i, 0, 640, 1, i);
+}
+
+tick-1ms
+/i == 320/
+{
+ printa(@);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d.out
new file mode 100644
index 0000000..68482ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggencoding.d.out
@@ -0,0 +1,646 @@
+
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 | 1
+ 2 |▏ 2
+ 3 |▎ 3
+ 4 |▍ 4
+ 5 |▌ 5
+ 6 |▋ 6
+ 7 |▊ 7
+ 8 |▉ 8
+ 9 |█ 9
+ 10 |█▏ 10
+ 11 |█▎ 11
+ 12 |█▍ 12
+ 13 |█▌ 13
+ 14 |█▋ 14
+ 15 |█▊ 15
+ 16 |█▉ 16
+ 17 |██ 17
+ 18 |██▏ 18
+ 19 |██▎ 19
+ 20 |██▍ 20
+ 21 |██▍ 21
+ 22 |██▌ 22
+ 23 |██▋ 23
+ 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
+ 69 |████████▏ 69
+ 70 |████████▎ 70
+ 71 |████████▍ 71
+ 72 |████████▌ 72
+ 73 |████████▋ 73
+ 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
+ 245 |█████████████████████████████ 245
+ 246 |█████████████████████████████▏ 246
+ 247 |█████████████████████████████▎ 247
+ 248 |█████████████████████████████▍ 248
+ 249 |█████████████████████████████▌ 249
+ 250 |█████████████████████████████▋ 250
+ 251 |█████████████████████████████▊ 251
+ 252 |█████████████████████████████▉ 252
+ 253 |██████████████████████████████ 253
+ 254 |██████████████████████████████▏ 254
+ 255 |██████████████████████████████▎ 255
+ 256 |██████████████████████████████▍ 256
+ 257 |██████████████████████████████▌ 257
+ 258 |██████████████████████████████▋ 258
+ 259 |██████████████████████████████▊ 259
+ 260 |██████████████████████████████▉ 260
+ 261 |██████████████████████████████▉ 261
+ 262 |███████████████████████████████ 262
+ 263 |███████████████████████████████▏ 263
+ 264 |███████████████████████████████▎ 264
+ 265 |███████████████████████████████▍ 265
+ 266 |███████████████████████████████▌ 266
+ 267 |███████████████████████████████▋ 267
+ 268 |███████████████████████████████▊ 268
+ 269 |███████████████████████████████▉ 269
+ 270 |████████████████████████████████ 270
+ 271 |████████████████████████████████▏ 271
+ 272 |████████████████████████████████▎ 272
+ 273 |████████████████████████████████▍ 273
+ 274 |████████████████████████████████▌ 274
+ 275 |████████████████████████████████▋ 275
+ 276 |████████████████████████████████▊ 276
+ 277 |████████████████████████████████▉ 277
+ 278 |█████████████████████████████████ 278
+ 279 |█████████████████████████████████▏ 279
+ 280 |█████████████████████████████████▎ 280
+ 281 |█████████████████████████████████▎ 281
+ 282 |█████████████████████████████████▍ 282
+ 283 |█████████████████████████████████▌ 283
+ 284 |█████████████████████████████████▋ 284
+ 285 |█████████████████████████████████▊ 285
+ 286 |█████████████████████████████████▉ 286
+ 287 |██████████████████████████████████ 287
+ 288 |██████████████████████████████████▏ 288
+ 289 |██████████████████████████████████▎ 289
+ 290 |██████████████████████████████████▍ 290
+ 291 |██████████████████████████████████▌ 291
+ 292 |██████████████████████████████████▋ 292
+ 293 |██████████████████████████████████▊ 293
+ 294 |██████████████████████████████████▉ 294
+ 295 |███████████████████████████████████ 295
+ 296 |███████████████████████████████████▏ 296
+ 297 |███████████████████████████████████▎ 297
+ 298 |███████████████████████████████████▍ 298
+ 299 |███████████████████████████████████▌ 299
+ 300 |███████████████████████████████████▋ 300
+ 301 |███████████████████████████████████▋ 301
+ 302 |███████████████████████████████████▊ 302
+ 303 |███████████████████████████████████▉ 303
+ 304 |████████████████████████████████████ 304
+ 305 |████████████████████████████████████▏ 305
+ 306 |████████████████████████████████████▎ 306
+ 307 |████████████████████████████████████▍ 307
+ 308 |████████████████████████████████████▌ 308
+ 309 |████████████████████████████████████▋ 309
+ 310 |████████████████████████████████████▊ 310
+ 311 |████████████████████████████████████▉ 311
+ 312 |█████████████████████████████████████ 312
+ 313 |█████████████████████████████████████▏ 313
+ 314 |█████████████████████████████████████▎ 314
+ 315 |█████████████████████████████████████▍ 315
+ 316 |█████████████████████████████████████▌ 316
+ 317 |█████████████████████████████████████▋ 317
+ 318 |█████████████████████████████████████▊ 318
+ 319 |█████████████████████████████████████▉ 319
+ 320 |██████████████████████████████████████ 320
+ 321 |██████████████████████████████████████ 320
+ 322 |█████████████████████████████████████▉ 319
+ 323 |█████████████████████████████████████▊ 318
+ 324 |█████████████████████████████████████▋ 317
+ 325 |█████████████████████████████████████▌ 316
+ 326 |█████████████████████████████████████▍ 315
+ 327 |█████████████████████████████████████▎ 314
+ 328 |█████████████████████████████████████▏ 313
+ 329 |█████████████████████████████████████ 312
+ 330 |████████████████████████████████████▉ 311
+ 331 |████████████████████████████████████▊ 310
+ 332 |████████████████████████████████████▋ 309
+ 333 |████████████████████████████████████▌ 308
+ 334 |████████████████████████████████████▍ 307
+ 335 |████████████████████████████████████▎ 306
+ 336 |████████████████████████████████████▏ 305
+ 337 |████████████████████████████████████ 304
+ 338 |███████████████████████████████████▉ 303
+ 339 |███████████████████████████████████▊ 302
+ 340 |███████████████████████████████████▋ 301
+ 341 |███████████████████████████████████▋ 300
+ 342 |███████████████████████████████████▌ 299
+ 343 |███████████████████████████████████▍ 298
+ 344 |███████████████████████████████████▎ 297
+ 345 |███████████████████████████████████▏ 296
+ 346 |███████████████████████████████████ 295
+ 347 |██████████████████████████████████▉ 294
+ 348 |██████████████████████████████████▊ 293
+ 349 |██████████████████████████████████▋ 292
+ 350 |██████████████████████████████████▌ 291
+ 351 |██████████████████████████████████▍ 290
+ 352 |██████████████████████████████████▎ 289
+ 353 |██████████████████████████████████▏ 288
+ 354 |██████████████████████████████████ 287
+ 355 |█████████████████████████████████▉ 286
+ 356 |█████████████████████████████████▊ 285
+ 357 |█████████████████████████████████▋ 284
+ 358 |█████████████████████████████████▌ 283
+ 359 |█████████████████████████████████▍ 282
+ 360 |█████████████████████████████████▎ 281
+ 361 |█████████████████████████████████▎ 280
+ 362 |█████████████████████████████████▏ 279
+ 363 |█████████████████████████████████ 278
+ 364 |████████████████████████████████▉ 277
+ 365 |████████████████████████████████▊ 276
+ 366 |████████████████████████████████▋ 275
+ 367 |████████████████████████████████▌ 274
+ 368 |████████████████████████████████▍ 273
+ 369 |████████████████████████████████▎ 272
+ 370 |████████████████████████████████▏ 271
+ 371 |████████████████████████████████ 270
+ 372 |███████████████████████████████▉ 269
+ 373 |███████████████████████████████▊ 268
+ 374 |███████████████████████████████▋ 267
+ 375 |███████████████████████████████▌ 266
+ 376 |███████████████████████████████▍ 265
+ 377 |███████████████████████████████▎ 264
+ 378 |███████████████████████████████▏ 263
+ 379 |███████████████████████████████ 262
+ 380 |██████████████████████████████▉ 261
+ 381 |██████████████████████████████▉ 260
+ 382 |██████████████████████████████▊ 259
+ 383 |██████████████████████████████▋ 258
+ 384 |██████████████████████████████▌ 257
+ 385 |██████████████████████████████▍ 256
+ 386 |██████████████████████████████▎ 255
+ 387 |██████████████████████████████▏ 254
+ 388 |██████████████████████████████ 253
+ 389 |█████████████████████████████▉ 252
+ 390 |█████████████████████████████▊ 251
+ 391 |█████████████████████████████▋ 250
+ 392 |█████████████████████████████▌ 249
+ 393 |█████████████████████████████▍ 248
+ 394 |█████████████████████████████▎ 247
+ 395 |█████████████████████████████▏ 246
+ 396 |█████████████████████████████ 245
+ 397 |████████████████████████████▉ 244
+ 398 |████████████████████████████▊ 243
+ 399 |████████████████████████████▋ 242
+ 400 |████████████████████████████▌ 241
+ 401 |████████████████████████████▌ 240
+ 402 |████████████████████████████▍ 239
+ 403 |████████████████████████████▎ 238
+ 404 |████████████████████████████▏ 237
+ 405 |████████████████████████████ 236
+ 406 |███████████████████████████▉ 235
+ 407 |███████████████████████████▊ 234
+ 408 |███████████████████████████▋ 233
+ 409 |███████████████████████████▌ 232
+ 410 |███████████████████████████▍ 231
+ 411 |███████████████████████████▎ 230
+ 412 |███████████████████████████▏ 229
+ 413 |███████████████████████████ 228
+ 414 |██████████████████████████▉ 227
+ 415 |██████████████████████████▊ 226
+ 416 |██████████████████████████▋ 225
+ 417 |██████████████████████████▌ 224
+ 418 |██████████████████████████▍ 223
+ 419 |██████████████████████████▎ 222
+ 420 |██████████████████████████▏ 221
+ 421 |██████████████████████████▏ 220
+ 422 |██████████████████████████ 219
+ 423 |█████████████████████████▉ 218
+ 424 |█████████████████████████▊ 217
+ 425 |█████████████████████████▋ 216
+ 426 |█████████████████████████▌ 215
+ 427 |█████████████████████████▍ 214
+ 428 |█████████████████████████▎ 213
+ 429 |█████████████████████████▏ 212
+ 430 |█████████████████████████ 211
+ 431 |████████████████████████▉ 210
+ 432 |████████████████████████▊ 209
+ 433 |████████████████████████▋ 208
+ 434 |████████████████████████▌ 207
+ 435 |████████████████████████▍ 206
+ 436 |████████████████████████▎ 205
+ 437 |████████████████████████▏ 204
+ 438 |████████████████████████ 203
+ 439 |███████████████████████▉ 202
+ 440 |███████████████████████▊ 201
+ 441 |███████████████████████▊ 200
+ 442 |███████████████████████▋ 199
+ 443 |███████████████████████▌ 198
+ 444 |███████████████████████▍ 197
+ 445 |███████████████████████▎ 196
+ 446 |███████████████████████▏ 195
+ 447 |███████████████████████ 194
+ 448 |██████████████████████▉ 193
+ 449 |██████████████████████▊ 192
+ 450 |██████████████████████▋ 191
+ 451 |██████████████████████▌ 190
+ 452 |██████████████████████▍ 189
+ 453 |██████████████████████▎ 188
+ 454 |██████████████████████▏ 187
+ 455 |██████████████████████ 186
+ 456 |█████████████████████▉ 185
+ 457 |█████████████████████▊ 184
+ 458 |█████████████████████▋ 183
+ 459 |█████████████████████▌ 182
+ 460 |█████████████████████▍ 181
+ 461 |█████████████████████▍ 180
+ 462 |█████████████████████▎ 179
+ 463 |█████████████████████▏ 178
+ 464 |█████████████████████ 177
+ 465 |████████████████████▉ 176
+ 466 |████████████████████▊ 175
+ 467 |████████████████████▋ 174
+ 468 |████████████████████▌ 173
+ 469 |████████████████████▍ 172
+ 470 |████████████████████▎ 171
+ 471 |████████████████████▏ 170
+ 472 |████████████████████ 169
+ 473 |███████████████████▉ 168
+ 474 |███████████████████▊ 167
+ 475 |███████████████████▋ 166
+ 476 |███████████████████▌ 165
+ 477 |███████████████████▍ 164
+ 478 |███████████████████▎ 163
+ 479 |███████████████████▏ 162
+ 480 |███████████████████ 161
+ 481 |███████████████████ 160
+ 482 |██████████████████▉ 159
+ 483 |██████████████████▊ 158
+ 484 |██████████████████▋ 157
+ 485 |██████████████████▌ 156
+ 486 |██████████████████▍ 155
+ 487 |██████████████████▎ 154
+ 488 |██████████████████▏ 153
+ 489 |██████████████████ 152
+ 490 |█████████████████▉ 151
+ 491 |█████████████████▊ 150
+ 492 |█████████████████▋ 149
+ 493 |█████████████████▌ 148
+ 494 |█████████████████▍ 147
+ 495 |█████████████████▎ 146
+ 496 |█████████████████▏ 145
+ 497 |█████████████████ 144
+ 498 |████████████████▉ 143
+ 499 |████████████████▊ 142
+ 500 |████████████████▋ 141
+ 501 |████████████████▋ 140
+ 502 |████████████████▌ 139
+ 503 |████████████████▍ 138
+ 504 |████████████████▎ 137
+ 505 |████████████████▏ 136
+ 506 |████████████████ 135
+ 507 |███████████████▉ 134
+ 508 |███████████████▊ 133
+ 509 |███████████████▋ 132
+ 510 |███████████████▌ 131
+ 511 |███████████████▍ 130
+ 512 |███████████████▎ 129
+ 513 |███████████████▏ 128
+ 514 |███████████████ 127
+ 515 |██████████████▉ 126
+ 516 |██████████████▊ 125
+ 517 |██████████████▋ 124
+ 518 |██████████████▌ 123
+ 519 |██████████████▍ 122
+ 520 |██████████████▎ 121
+ 521 |██████████████▎ 120
+ 522 |██████████████▏ 119
+ 523 |██████████████ 118
+ 524 |█████████████▉ 117
+ 525 |█████████████▊ 116
+ 526 |█████████████▋ 115
+ 527 |█████████████▌ 114
+ 528 |█████████████▍ 113
+ 529 |█████████████▎ 112
+ 530 |█████████████▏ 111
+ 531 |█████████████ 110
+ 532 |████████████▉ 109
+ 533 |████████████▊ 108
+ 534 |████████████▋ 107
+ 535 |████████████▌ 106
+ 536 |████████████▍ 105
+ 537 |████████████▎ 104
+ 538 |████████████▏ 103
+ 539 |████████████ 102
+ 540 |███████████▉ 101
+ 541 |███████████▉ 100
+ 542 |███████████▊ 99
+ 543 |███████████▋ 98
+ 544 |███████████▌ 97
+ 545 |███████████▍ 96
+ 546 |███████████▎ 95
+ 547 |███████████▏ 94
+ 548 |███████████ 93
+ 549 |██████████▉ 92
+ 550 |██████████▊ 91
+ 551 |██████████▋ 90
+ 552 |██████████▌ 89
+ 553 |██████████▍ 88
+ 554 |██████████▎ 87
+ 555 |██████████▏ 86
+ 556 |██████████ 85
+ 557 |█████████▉ 84
+ 558 |█████████▊ 83
+ 559 |█████████▋ 82
+ 560 |█████████▌ 81
+ 561 |█████████▌ 80
+ 562 |█████████▍ 79
+ 563 |█████████▎ 78
+ 564 |█████████▏ 77
+ 565 |█████████ 76
+ 566 |████████▉ 75
+ 567 |████████▊ 74
+ 568 |████████▋ 73
+ 569 |████████▌ 72
+ 570 |████████▍ 71
+ 571 |████████▎ 70
+ 572 |████████▏ 69
+ 573 |████████ 68
+ 574 |███████▉ 67
+ 575 |███████▊ 66
+ 576 |███████▋ 65
+ 577 |███████▌ 64
+ 578 |███████▍ 63
+ 579 |███████▎ 62
+ 580 |███████▏ 61
+ 581 |███████▏ 60
+ 582 |███████ 59
+ 583 |██████▉ 58
+ 584 |██████▊ 57
+ 585 |██████▋ 56
+ 586 |██████▌ 55
+ 587 |██████▍ 54
+ 588 |██████▎ 53
+ 589 |██████▏ 52
+ 590 |██████ 51
+ 591 |█████▉ 50
+ 592 |█████▊ 49
+ 593 |█████▋ 48
+ 594 |█████▌ 47
+ 595 |█████▍ 46
+ 596 |█████▎ 45
+ 597 |█████▏ 44
+ 598 |█████ 43
+ 599 |████▉ 42
+ 600 |████▊ 41
+ 601 |████▊ 40
+ 602 |████▋ 39
+ 603 |████▌ 38
+ 604 |████▍ 37
+ 605 |████▎ 36
+ 606 |████▏ 35
+ 607 |████ 34
+ 608 |███▉ 33
+ 609 |███▊ 32
+ 610 |███▋ 31
+ 611 |███▌ 30
+ 612 |███▍ 29
+ 613 |███▎ 28
+ 614 |███▏ 27
+ 615 |███ 26
+ 616 |██▉ 25
+ 617 |██▊ 24
+ 618 |██▋ 23
+ 619 |██▌ 22
+ 620 |██▍ 21
+ 621 |██▍ 20
+ 622 |██▎ 19
+ 623 |██▏ 18
+ 624 |██ 17
+ 625 |█▉ 16
+ 626 |█▊ 15
+ 627 |█▋ 14
+ 628 |█▌ 13
+ 629 |█▍ 12
+ 630 |█▎ 11
+ 631 |█▏ 10
+ 632 |█ 9
+ 633 |▉ 8
+ 634 |▊ 7
+ 635 |▋ 6
+ 636 |▌ 5
+ 637 |▍ 4
+ 638 |▎ 3
+ 639 |▏ 2
+ >= 640 | 1
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d
new file mode 100644
index 0000000..317aece
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d
@@ -0,0 +1,46 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option agghist
+#pragma D option quiet
+
+BEGIN
+{
+ @["demerit"] = sum(-10);
+ @["wtf"] = sum(10);
+ @["bot"] = sum(20);
+
+ @bagnoogle["SOAP/XML"] = sum(1);
+ @bagnoogle["XACML store"] = sum(5);
+ @bagnoogle["SAML token"] = sum(6);
+
+ @stalloogle["breakfast"] = sum(-5);
+ @stalloogle["non-diet pepsi"] = sum(-20);
+ @stalloogle["parrot"] = sum(-100);
+
+ printa(@);
+ printa(@bagnoogle);
+ printa(@stalloogle);
+
+ printf("\nzoomed:");
+
+ setopt("aggzoom");
+ printa(@);
+ printa(@bagnoogle);
+ printa(@stalloogle);
+
+ exit(0);
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d.out
new file mode 100644
index 0000000..d76e4da
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.agghist.d.out
@@ -0,0 +1,38 @@
+
+
+ key ------------- Distribution ------------- count
+ demerit @@@@@| -10
+ wtf |@@@@@ 10
+ bot |@@@@@@@@@@ 20
+
+
+ key ------------- Distribution ------------- count
+ SOAP/XML |@@@ 1
+ XACML store |@@@@@@@@@@@@@@@@@ 5
+ SAML token |@@@@@@@@@@@@@@@@@@@@ 6
+
+
+ key ------------- Distribution ------------- count
+ parrot @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -100
+ non-diet pepsi @@@@@@| -20
+ breakfast @@| -5
+
+zoomed:
+
+ key ------------- Distribution ------------- count
+ demerit @@@@@@@@@@| -10
+ wtf |@@@@@@@@@@ 10
+ bot |@@@@@@@@@@@@@@@@@@@ 20
+
+
+ key ------------- Distribution ------------- count
+ SOAP/XML |@@@@@@@ 1
+ XACML store |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5
+ SAML token |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6
+
+
+ key ------------- Distribution ------------- count
+ parrot @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| -100
+ non-diet pepsi @@@@@@@@| -20
+ breakfast @@| -5
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d
new file mode 100644
index 0000000..c9fdba7
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d
@@ -0,0 +1,53 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option aggpack
+#pragma D option encoding=ascii
+#pragma D option quiet
+
+BEGIN
+{
+ @x = quantize(1 << 32);
+ @y[1] = quantize(1);
+ @z["mumble"] = quantize(1);
+ @xx["foo", (char)1, (short)2, (long)3] = quantize(1);
+
+ @neg = lquantize(-10, -10, 20, 1, -1);
+ @neg = lquantize(-5, -10, 20, 1, 1);
+ @neg = lquantize(0, -10, 20, 1, 1);
+
+ i = 0;
+}
+
+tick-1ms
+{
+ @a[i] = quantize(0, i);
+ @a[i] = quantize(1, 100 - i);
+ i++;
+}
+
+tick-1ms
+/i > 100/
+{
+ exit(0);
+}
+
+END
+{
+ setopt("aggzoom", "true");
+ printa(@neg);
+ setopt("aggzoom", "false");
+ printa(@neg);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d.out
new file mode 100644
index 0000000..5300ebd
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpack.d.out
@@ -0,0 +1,124 @@
+
+
+ min .--------------------------------. max | count
+ < -10 : V X X : >= 20 | 1
+
+
+ min .--------------------------------. max | count
+ < -10 : v x x : >= 20 | 1
+
+
+ min .---. max | count
+ 2147483648 : X : 8589934592 | 1
+
+ key min .---. max | count
+ 1 0 : X : 2 | 1
+
+ key min .---. max | count
+ mumble 0 : X : 2 | 1
+
+ key min .---. max | count
+ foo 1 2 3 0 : X : 2 | 1
+
+ key min .---. max | count
+ 100 0 :X : 2 | 100
+ 99 0 :X_ : 2 | 100
+ 98 0 :X_ : 2 | 100
+ 97 0 :X_ : 2 | 100
+ 96 0 :X_ : 2 | 100
+ 95 0 :X_ : 2 | 100
+ 94 0 :X_ : 2 | 100
+ 93 0 :X_ : 2 | 100
+ 92 0 :X_ : 2 | 100
+ 91 0 :X_ : 2 | 100
+ 90 0 :X_ : 2 | 100
+ 89 0 :X_ : 2 | 100
+ 88 0 :X_ : 2 | 100
+ 87 0 :X_ : 2 | 100
+ 86 0 :X_ : 2 | 100
+ 85 0 :X_ : 2 | 100
+ 84 0 :X_ : 2 | 100
+ 83 0 :X_ : 2 | 100
+ 82 0 :X_ : 2 | 100
+ 81 0 :X_ : 2 | 100
+ 80 0 :X_ : 2 | 100
+ 79 0 :X_ : 2 | 100
+ 78 0 :xx : 2 | 100
+ 77 0 :xx : 2 | 100
+ 76 0 :xx : 2 | 100
+ 75 0 :xx : 2 | 100
+ 74 0 :xx : 2 | 100
+ 73 0 :xx : 2 | 100
+ 72 0 :xx : 2 | 100
+ 71 0 :xx : 2 | 100
+ 70 0 :xx : 2 | 100
+ 69 0 :xx : 2 | 100
+ 68 0 :xx : 2 | 100
+ 67 0 :xx : 2 | 100
+ 66 0 :xx : 2 | 100
+ 65 0 :xx : 2 | 100
+ 64 0 :xx : 2 | 100
+ 63 0 :xx : 2 | 100
+ 62 0 :xx : 2 | 100
+ 61 0 :xx : 2 | 100
+ 60 0 :xx : 2 | 100
+ 59 0 :xx : 2 | 100
+ 58 0 :xx : 2 | 100
+ 57 0 :xx : 2 | 100
+ 56 0 :xx : 2 | 100
+ 55 0 :xx : 2 | 100
+ 54 0 :xx : 2 | 100
+ 53 0 :xx : 2 | 100
+ 52 0 :xx : 2 | 100
+ 51 0 :xx : 2 | 100
+ 50 0 :xx : 2 | 100
+ 49 0 :xx : 2 | 100
+ 48 0 :xx : 2 | 100
+ 47 0 :xx : 2 | 100
+ 46 0 :xx : 2 | 100
+ 45 0 :xx : 2 | 100
+ 44 0 :xx : 2 | 100
+ 43 0 :xx : 2 | 100
+ 42 0 :xx : 2 | 100
+ 41 0 :xx : 2 | 100
+ 40 0 :xx : 2 | 100
+ 39 0 :xx : 2 | 100
+ 38 0 :xx : 2 | 100
+ 37 0 :xx : 2 | 100
+ 36 0 :xx : 2 | 100
+ 35 0 :xx : 2 | 100
+ 34 0 :xx : 2 | 100
+ 33 0 :xx : 2 | 100
+ 32 0 :xx : 2 | 100
+ 31 0 :xx : 2 | 100
+ 30 0 :xx : 2 | 100
+ 29 0 :xx : 2 | 100
+ 28 0 :xx : 2 | 100
+ 27 0 :xx : 2 | 100
+ 26 0 :xx : 2 | 100
+ 25 0 :xx : 2 | 100
+ 24 0 :xx : 2 | 100
+ 23 0 :xx : 2 | 100
+ 22 0 :xx : 2 | 100
+ 21 0 :_X : 2 | 100
+ 20 0 :_X : 2 | 100
+ 19 0 :_X : 2 | 100
+ 18 0 :_X : 2 | 100
+ 17 0 :_X : 2 | 100
+ 16 0 :_X : 2 | 100
+ 15 0 :_X : 2 | 100
+ 14 0 :_X : 2 | 100
+ 13 0 :_X : 2 | 100
+ 12 0 :_X : 2 | 100
+ 11 0 :_X : 2 | 100
+ 10 0 :_X : 2 | 100
+ 9 0 :_X : 2 | 100
+ 8 0 :_X : 2 | 100
+ 7 0 :_X : 2 | 100
+ 6 0 :_X : 2 | 100
+ 5 0 :_X : 2 | 100
+ 4 0 :_X : 2 | 100
+ 3 0 :_X : 2 | 100
+ 2 0 :_X : 2 | 100
+ 1 0 :_X : 2 | 100
+ 0 0 : X : 2 | 100
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh
new file mode 100644
index 0000000..f055a08
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh
@@ -0,0 +1,75 @@
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+let width=8
+
+function outputchar
+{
+ banner $3 | /bin/nawk -v line=$1 -v pos=$2 -v width=$width '{ \
+ for (i = 1; i <= length($0); i++) { \
+ if (substr($0, i, 1) == " ") \
+ continue; \
+ printf("\t@letter%d[%d] = lquantize(%d, 0, 40, 1);\n", \
+ line, NR, i + (pos * width));
+ } \
+ }'
+}
+
+function outputstr
+{
+ let pos=0;
+ let line=0
+
+ printf "#pragma D option aggpack\n#pragma D option aggsortkey\n"
+
+ printf "BEGIN\n{\n"
+ for c in `echo "$1" | /bin/nawk '{ \
+ for (i = 1; i <= length($0); i++) { \
+ c = substr($0, i, 1); \
+ printf("%s\n", c == " " ? "space" : \
+ c == "\n" ? "newline" : c); \
+ } \
+ }'`; do
+ if [[ "$c" == "space" ]]; then
+ let line=line+1
+ let pos=0
+ continue
+ fi
+
+ outputchar $line $pos $c
+ let pos=pos+1
+ done
+
+ let i=0
+
+ while [[ $i -le $line ]]; do
+ printf "\tprinta(@letter%d);\n" $i
+ let i=i+1
+ done
+ printf "\texit(0);\n}\n"
+}
+
+dtrace -qs /dev/stdin -x encoding=utf8 <<EOF
+`outputstr "why must i do this"`
+EOF
+
+dtrace -qs /dev/stdin -x encoding=ascii -x aggzoom <<EOF
+`outputstr "i am not well"`
+EOF
+
+dtrace -qs /dev/stdin -x encoding=utf8 -x aggzoom <<EOF
+`outputstr "send help"`
+EOF
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh.out
new file mode 100644
index 0000000..a7eba38
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackbanner.ksh.out
@@ -0,0 +1,102 @@
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6
+ 3 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6
+ 4 < 0 : ▂ ▂ ▂▂▂▂▂▂ ▂ : >= 40 | 9
+ 5 < 0 : ▂ ▂▂ ▂ ▂ ▂ ▂ : >= 40 | 7
+ 6 < 0 : ▂▂ ▂▂ ▂ ▂ ▂ : >= 40 | 7
+ 7 < 0 : ▂ ▂ ▂ ▂ ▂ : >= 40 | 5
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : ▂ ▂ ▂ ▂ ▂▂▂▂ ▂▂▂▂▂ : >= 40 | 13
+ 3 < 0 : ▂▂ ▂▂ ▂ ▂ ▂ ▂ : >= 40 | 8
+ 4 < 0 : ▂ ▂▂ ▂ ▂ ▂ ▂▂▂▂ ▂ : >= 40 | 11
+ 5 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6
+ 6 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 7
+ 7 < 0 : ▂ ▂ ▂▂▂▂ ▂▂▂▂ ▂ : >= 40 | 11
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : █ : >= 40 | 1
+ 3 < 0 : █ : >= 40 | 1
+ 4 < 0 : █ : >= 40 | 1
+ 5 < 0 : █ : >= 40 | 1
+ 6 < 0 : █ : >= 40 | 1
+ 7 < 0 : █ : >= 40 | 1
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : ▂▂▂▂▂ ▂▂▂▂ : >= 40 | 9
+ 3 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4
+ 4 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4
+ 5 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4
+ 6 < 0 : ▃ ▃ ▃ ▃ : >= 40 | 4
+ 7 < 0 : ▂▂▂▂▂ ▂▂▂▂ : >= 40 | 9
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : ▂▂▂▂▂ ▂ ▂ ▂ ▂▂▂▂ : >= 40 | 12
+ 3 < 0 : ▂ ▂ ▂ ▂ ▂ : >= 40 | 5
+ 4 < 0 : ▂ ▂▂▂▂▂▂ ▂ ▂▂▂▂ : >= 40 | 12
+ 5 < 0 : ▂ ▂ ▂ ▂ ▂ : >= 40 | 5
+ 6 < 0 : ▂ ▂ ▂ ▂ ▂ ▂ : >= 40 | 6
+ 7 < 0 : ▂ ▂ ▂ ▂ ▂▂▂▂ : >= 40 | 8
+
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : X : >= 40 | 1
+ 3 < 0 : X : >= 40 | 1
+ 4 < 0 : X : >= 40 | 1
+ 5 < 0 : X : >= 40 | 1
+ 6 < 0 : X : >= 40 | 1
+ 7 < 0 : X : >= 40 | 1
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : XX X X : >= 40 | 4
+ 3 < 0 : X X XX XX : >= 40 | 6
+ 4 < 0 : X X X XX X : >= 40 | 6
+ 5 < 0 : XXXXXX X X : >= 40 | 8
+ 6 < 0 : X X X X : >= 40 | 4
+ 7 < 0 : X X X X : >= 40 | 4
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : X X XXXX XXXXX : >= 40 | 11
+ 3 < 0 : XX X X X X : >= 40 | 6
+ 4 < 0 : X X X X X X : >= 40 | 6
+ 5 < 0 : X X X X X X : >= 40 | 6
+ 6 < 0 : X XX X X X : >= 40 | 6
+ 7 < 0 : X X XXXX X : >= 40 | 7
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : X X XXXXXX X X : >= 40 | 10
+ 3 < 0 : X X X X X : >= 40 | 5
+ 4 < 0 : X X XXXXX X X : >= 40 | 9
+ 5 < 0 : X XX X X X X : >= 40 | 7
+ 6 < 0 : XX XX X X X : >= 40 | 7
+ 7 < 0 : X X XXXXXX XXXXXX XXXXXX : >= 40 | 20
+
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : ████ ██████ █ █ █████ : >= 40 | 17
+ 3 < 0 : █ █ ██ █ █ █ : >= 40 | 7
+ 4 < 0 : ████ █████ █ █ █ █ █ : >= 40 | 14
+ 5 < 0 : █ █ █ █ █ █ █ : >= 40 | 7
+ 6 < 0 : █ █ █ █ ██ █ █ : >= 40 | 8
+ 7 < 0 : ████ ██████ █ █ █████ : >= 40 | 17
+
+
+ key min .------------------------------------------. max | count
+ 2 < 0 : █ █ ██████ █ █████ : >= 40 | 14
+ 3 < 0 : █ █ █ █ █ █ : >= 40 | 6
+ 4 < 0 : ██████ █████ █ █ █ : >= 40 | 14
+ 5 < 0 : █ █ █ █ █████ : >= 40 | 9
+ 6 < 0 : █ █ █ █ █ : >= 40 | 5
+ 7 < 0 : █ █ ██████ ██████ █ : >= 40 | 15
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d
new file mode 100644
index 0000000..2f297e2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d
@@ -0,0 +1,43 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option encoding=ascii
+#pragma D option quiet
+
+tick-1ms
+/i++ < 30/
+{
+ @[1] = lquantize(i, 0, 40, 1, 1000);
+ @[2] = lquantize(i, 0, 40, 1, 1000);
+ @[3] = lquantize(i, 0, 40, 1, 1000);
+}
+
+tick-1ms
+/i == 40/
+{
+ @[1] = lquantize(0, 0, 40, 1, 1);
+ @[1] = lquantize(i, 0, 40, 1, 2000);
+ @[2] = lquantize(0, 0, 40, 1, 1);
+ @[2] = lquantize(i, 0, 40, 1, 2000);
+ @[3] = lquantize(0, 0, 40, 1, 1);
+ @[3] = lquantize(i, 0, 40, 1, 2000);
+
+ printa(@);
+ setopt("aggpack");
+ printa(@);
+ setopt("aggzoom");
+ printa(@);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d.out
new file mode 100644
index 0000000..a22a2a4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggpackzoom.d.out
@@ -0,0 +1,149 @@
+
+ 1
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 | 1
+ 1 |@ 1000
+ 2 |@ 1000
+ 3 |@ 1000
+ 4 |@ 1000
+ 5 |@ 1000
+ 6 |@ 1000
+ 7 |@ 1000
+ 8 |@ 1000
+ 9 |@ 1000
+ 10 |@ 1000
+ 11 |@ 1000
+ 12 |@ 1000
+ 13 |@ 1000
+ 14 |@ 1000
+ 15 |@ 1000
+ 16 |@ 1000
+ 17 |@ 1000
+ 18 |@ 1000
+ 19 |@ 1000
+ 20 |@ 1000
+ 21 |@ 1000
+ 22 |@ 1000
+ 23 |@ 1000
+ 24 |@ 1000
+ 25 |@ 1000
+ 26 |@ 1000
+ 27 |@ 1000
+ 28 |@ 1000
+ 29 |@ 1000
+ 30 |@ 1000
+ 31 | 0
+ 32 | 0
+ 33 | 0
+ 34 | 0
+ 35 | 0
+ 36 | 0
+ 37 | 0
+ 38 | 0
+ 39 | 0
+ >= 40 |@@ 2000
+
+ 2
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 | 1
+ 1 |@ 1000
+ 2 |@ 1000
+ 3 |@ 1000
+ 4 |@ 1000
+ 5 |@ 1000
+ 6 |@ 1000
+ 7 |@ 1000
+ 8 |@ 1000
+ 9 |@ 1000
+ 10 |@ 1000
+ 11 |@ 1000
+ 12 |@ 1000
+ 13 |@ 1000
+ 14 |@ 1000
+ 15 |@ 1000
+ 16 |@ 1000
+ 17 |@ 1000
+ 18 |@ 1000
+ 19 |@ 1000
+ 20 |@ 1000
+ 21 |@ 1000
+ 22 |@ 1000
+ 23 |@ 1000
+ 24 |@ 1000
+ 25 |@ 1000
+ 26 |@ 1000
+ 27 |@ 1000
+ 28 |@ 1000
+ 29 |@ 1000
+ 30 |@ 1000
+ 31 | 0
+ 32 | 0
+ 33 | 0
+ 34 | 0
+ 35 | 0
+ 36 | 0
+ 37 | 0
+ 38 | 0
+ 39 | 0
+ >= 40 |@@ 2000
+
+ 3
+ value ------------- Distribution ------------- count
+ < 0 | 0
+ 0 | 1
+ 1 |@ 1000
+ 2 |@ 1000
+ 3 |@ 1000
+ 4 |@ 1000
+ 5 |@ 1000
+ 6 |@ 1000
+ 7 |@ 1000
+ 8 |@ 1000
+ 9 |@ 1000
+ 10 |@ 1000
+ 11 |@ 1000
+ 12 |@ 1000
+ 13 |@ 1000
+ 14 |@ 1000
+ 15 |@ 1000
+ 16 |@ 1000
+ 17 |@ 1000
+ 18 |@ 1000
+ 19 |@ 1000
+ 20 |@ 1000
+ 21 |@ 1000
+ 22 |@ 1000
+ 23 |@ 1000
+ 24 |@ 1000
+ 25 |@ 1000
+ 26 |@ 1000
+ 27 |@ 1000
+ 28 |@ 1000
+ 29 |@ 1000
+ 30 |@ 1000
+ 31 | 0
+ 32 | 0
+ 33 | 0
+ 34 | 0
+ 35 | 0
+ 36 | 0
+ 37 | 0
+ 38 | 0
+ 39 | 0
+ >= 40 |@@ 2000
+
+
+
+ key min .------------------------------------------. max | count
+ 1 < 0 : _______________________________ _: >= 40 | 32001
+ 2 < 0 : _______________________________ _: >= 40 | 32001
+ 3 < 0 : _______________________________ _: >= 40 | 32001
+
+
+ key min .------------------------------------------. max | count
+ 1 < 0 : _xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X: >= 40 | 32001
+ 2 < 0 : _xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X: >= 40 | 32001
+ 3 < 0 : _xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X: >= 40 | 32001
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d
new file mode 100644
index 0000000..f237d26
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d
@@ -0,0 +1,35 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option encoding=ascii
+#pragma D option quiet
+
+tick-1ms
+/i++ < 90/
+{
+ @ = lquantize(i, 0, 100, 1, 1000);
+}
+
+tick-1ms
+/i == 100/
+{
+ @ = lquantize(i++, 0, 100, 1, 2000);
+ @ = lquantize(i++, 0, 100, 1, 3000);
+
+ printa(@);
+ setopt("aggzoom");
+ printa(@);
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d.out
new file mode 100644
index 0000000..acddf7f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.aggzoom.d.out
@@ -0,0 +1,211 @@
+
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 | 1000
+ 2 | 1000
+ 3 | 1000
+ 4 | 1000
+ 5 | 1000
+ 6 | 1000
+ 7 | 1000
+ 8 | 1000
+ 9 | 1000
+ 10 | 1000
+ 11 | 1000
+ 12 | 1000
+ 13 | 1000
+ 14 | 1000
+ 15 | 1000
+ 16 | 1000
+ 17 | 1000
+ 18 | 1000
+ 19 | 1000
+ 20 | 1000
+ 21 | 1000
+ 22 | 1000
+ 23 | 1000
+ 24 | 1000
+ 25 | 1000
+ 26 | 1000
+ 27 | 1000
+ 28 | 1000
+ 29 | 1000
+ 30 | 1000
+ 31 | 1000
+ 32 | 1000
+ 33 | 1000
+ 34 | 1000
+ 35 | 1000
+ 36 | 1000
+ 37 | 1000
+ 38 | 1000
+ 39 | 1000
+ 40 | 1000
+ 41 | 1000
+ 42 | 1000
+ 43 | 1000
+ 44 | 1000
+ 45 | 1000
+ 46 | 1000
+ 47 | 1000
+ 48 | 1000
+ 49 | 1000
+ 50 | 1000
+ 51 | 1000
+ 52 | 1000
+ 53 | 1000
+ 54 | 1000
+ 55 | 1000
+ 56 | 1000
+ 57 | 1000
+ 58 | 1000
+ 59 | 1000
+ 60 | 1000
+ 61 | 1000
+ 62 | 1000
+ 63 | 1000
+ 64 | 1000
+ 65 | 1000
+ 66 | 1000
+ 67 | 1000
+ 68 | 1000
+ 69 | 1000
+ 70 | 1000
+ 71 | 1000
+ 72 | 1000
+ 73 | 1000
+ 74 | 1000
+ 75 | 1000
+ 76 | 1000
+ 77 | 1000
+ 78 | 1000
+ 79 | 1000
+ 80 | 1000
+ 81 | 1000
+ 82 | 1000
+ 83 | 1000
+ 84 | 1000
+ 85 | 1000
+ 86 | 1000
+ 87 | 1000
+ 88 | 1000
+ 89 | 1000
+ 90 | 1000
+ 91 | 0
+ 92 | 0
+ 93 | 0
+ 94 | 0
+ 95 | 0
+ 96 | 0
+ 97 | 0
+ 98 | 0
+ 99 | 0
+ >= 100 |@@ 5000
+
+
+
+ value ------------- Distribution ------------- count
+ 0 | 0
+ 1 |@@@@@@@@ 1000
+ 2 |@@@@@@@@ 1000
+ 3 |@@@@@@@@ 1000
+ 4 |@@@@@@@@ 1000
+ 5 |@@@@@@@@ 1000
+ 6 |@@@@@@@@ 1000
+ 7 |@@@@@@@@ 1000
+ 8 |@@@@@@@@ 1000
+ 9 |@@@@@@@@ 1000
+ 10 |@@@@@@@@ 1000
+ 11 |@@@@@@@@ 1000
+ 12 |@@@@@@@@ 1000
+ 13 |@@@@@@@@ 1000
+ 14 |@@@@@@@@ 1000
+ 15 |@@@@@@@@ 1000
+ 16 |@@@@@@@@ 1000
+ 17 |@@@@@@@@ 1000
+ 18 |@@@@@@@@ 1000
+ 19 |@@@@@@@@ 1000
+ 20 |@@@@@@@@ 1000
+ 21 |@@@@@@@@ 1000
+ 22 |@@@@@@@@ 1000
+ 23 |@@@@@@@@ 1000
+ 24 |@@@@@@@@ 1000
+ 25 |@@@@@@@@ 1000
+ 26 |@@@@@@@@ 1000
+ 27 |@@@@@@@@ 1000
+ 28 |@@@@@@@@ 1000
+ 29 |@@@@@@@@ 1000
+ 30 |@@@@@@@@ 1000
+ 31 |@@@@@@@@ 1000
+ 32 |@@@@@@@@ 1000
+ 33 |@@@@@@@@ 1000
+ 34 |@@@@@@@@ 1000
+ 35 |@@@@@@@@ 1000
+ 36 |@@@@@@@@ 1000
+ 37 |@@@@@@@@ 1000
+ 38 |@@@@@@@@ 1000
+ 39 |@@@@@@@@ 1000
+ 40 |@@@@@@@@ 1000
+ 41 |@@@@@@@@ 1000
+ 42 |@@@@@@@@ 1000
+ 43 |@@@@@@@@ 1000
+ 44 |@@@@@@@@ 1000
+ 45 |@@@@@@@@ 1000
+ 46 |@@@@@@@@ 1000
+ 47 |@@@@@@@@ 1000
+ 48 |@@@@@@@@ 1000
+ 49 |@@@@@@@@ 1000
+ 50 |@@@@@@@@ 1000
+ 51 |@@@@@@@@ 1000
+ 52 |@@@@@@@@ 1000
+ 53 |@@@@@@@@ 1000
+ 54 |@@@@@@@@ 1000
+ 55 |@@@@@@@@ 1000
+ 56 |@@@@@@@@ 1000
+ 57 |@@@@@@@@ 1000
+ 58 |@@@@@@@@ 1000
+ 59 |@@@@@@@@ 1000
+ 60 |@@@@@@@@ 1000
+ 61 |@@@@@@@@ 1000
+ 62 |@@@@@@@@ 1000
+ 63 |@@@@@@@@ 1000
+ 64 |@@@@@@@@ 1000
+ 65 |@@@@@@@@ 1000
+ 66 |@@@@@@@@ 1000
+ 67 |@@@@@@@@ 1000
+ 68 |@@@@@@@@ 1000
+ 69 |@@@@@@@@ 1000
+ 70 |@@@@@@@@ 1000
+ 71 |@@@@@@@@ 1000
+ 72 |@@@@@@@@ 1000
+ 73 |@@@@@@@@ 1000
+ 74 |@@@@@@@@ 1000
+ 75 |@@@@@@@@ 1000
+ 76 |@@@@@@@@ 1000
+ 77 |@@@@@@@@ 1000
+ 78 |@@@@@@@@ 1000
+ 79 |@@@@@@@@ 1000
+ 80 |@@@@@@@@ 1000
+ 81 |@@@@@@@@ 1000
+ 82 |@@@@@@@@ 1000
+ 83 |@@@@@@@@ 1000
+ 84 |@@@@@@@@ 1000
+ 85 |@@@@@@@@ 1000
+ 86 |@@@@@@@@ 1000
+ 87 |@@@@@@@@ 1000
+ 88 |@@@@@@@@ 1000
+ 89 |@@@@@@@@ 1000
+ 90 |@@@@@@@@ 1000
+ 91 | 0
+ 92 | 0
+ 93 | 0
+ 94 | 0
+ 95 | 0
+ 96 | 0
+ 97 | 0
+ 98 | 0
+ 99 | 0
+ >= 100 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5000
+
+
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
index d508596..9b02e98 100644
--- 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
@@ -22,6 +22,7 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -97,6 +98,9 @@ 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))))
+INTFUNC(getf(0))
+INTFUNC(strtoll("0x12EE5D5", 16))
+STRFUNC(json("{\"systemtap\": false}", "systemtap"))
BEGIN
/subr == DIF_SUBR_MAX + 1/
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d
new file mode 100644
index 0000000..4600811
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d
@@ -0,0 +1,179 @@
+/*
+ * 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, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * General functional tests of JSON parser for json().
+ */
+
+#pragma D option quiet
+#pragma D option strsize=1k
+
+#define TST(name) \
+ printf("\ntst |%s|\n", name)
+#define IN2(vala, valb) \
+ in = strjoin(vala, valb); \
+ printf("in |%s|\n", in)
+#define IN(val) \
+ in = val; \
+ printf("in |%s|\n", in)
+#define SEL(ss) \
+ out = json(in, ss); \
+ printf("sel |%s|\nout |%s|\n", ss, \
+ out != NULL ? out : "<NULL>")
+
+BEGIN
+{
+ TST("empty array");
+ IN("[]");
+ SEL("0");
+
+ TST("one-element array: integer");
+ IN("[1]");
+ SEL("0");
+ SEL("1");
+ SEL("100");
+ SEL("-1");
+
+ TST("one-element array: hex integer (not in spec, not supported)");
+ IN("[0x1000]");
+ SEL("0");
+
+ TST("one-element array: float");
+ IN("[1.5001]");
+ SEL("0");
+
+ TST("one-element array: float + exponent");
+ IN("[16.3e10]");
+ SEL("0");
+
+ TST("one-element array: integer + whitespace");
+ IN("[ \t 5\t]");
+ SEL("0");
+
+ TST("one-element array: integer + exponent + whitespace");
+ IN("[ \t \t 16E10 \t ]");
+ SEL("0");
+
+ TST("one-element array: string");
+ IN("[\"alpha\"]");
+ SEL("0");
+
+ TST("alternative first-element indexing");
+ IN("[1,5,10,15,20]");
+ SEL("[0]");
+ SEL("[3]");
+ SEL("[4]");
+ SEL("[5]");
+
+ TST("one-element array: object");
+ IN("[ { \"first\": true, \"second\": false }]");
+ SEL("0.first");
+ SEL("0.second");
+ SEL("0.third");
+
+ TST("many-element array: integers");
+ IN("[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]");
+ SEL("10"); /* F(10) = 55 */
+ SEL("14"); /* F(14) = 377 */
+ SEL("19");
+
+ TST("many-element array: multiple types");
+ IN2("[\"string\",32,true,{\"a\":9,\"b\":false},100.3e10,false,200.5,",
+ "{\"key\":\"val\"},null]");
+ SEL("0");
+ SEL("0.notobject");
+ SEL("1");
+ SEL("2");
+ SEL("3");
+ SEL("3.a");
+ SEL("3.b");
+ SEL("3.c");
+ SEL("4");
+ SEL("5");
+ SEL("6");
+ SEL("7");
+ SEL("7.key");
+ SEL("7.key.notobject");
+ SEL("7.nonexist");
+ SEL("8");
+ SEL("9");
+
+ TST("many-element array: multiple types + whitespace");
+ IN2("\n[\t\"string\" ,\t32 , true\t,\t {\"a\": 9,\t\"b\": false},\t\t",
+ "100.3e10, false, 200.5,{\"key\" \t:\n \"val\"},\t\t null ]\t\t");
+ SEL("0");
+ SEL("0.notobject");
+ SEL("1");
+ SEL("2");
+ SEL("3");
+ SEL("3.a");
+ SEL("3.b");
+ SEL("3.c");
+ SEL("4");
+ SEL("5");
+ SEL("6");
+ SEL("7");
+ SEL("7.key");
+ SEL("7.key.notobject");
+ SEL("7.nonexist");
+ SEL("8");
+ SEL("9");
+
+ TST("two-element array: various string escape codes");
+ IN2("[\"abcd \\\" \\\\ \\/ \\b \\f \\n \\r \\t \\u0000 \\uf00F \", ",
+ "\"final\"]");
+ SEL("0");
+ SEL("1");
+
+ TST("three-element array: broken escape code");
+ IN("[\"fine here\", \"dodgey \\u00AZ\", \"wont get here\"]");
+ SEL("0");
+ SEL("1");
+ SEL("2");
+
+ TST("nested objects");
+ IN2("{ \"top\": { \"mid\" : { \"legs\": \"feet\" }, \"number\": 9, ",
+ "\"array\":[0,1,{\"a\":true,\"bb\":[1,2,false,{\"x\":\"yz\"}]}]}}");
+ SEL("top");
+ SEL("fargo");
+ SEL("top.mid");
+ SEL("top.centre");
+ SEL("top.mid.legs");
+ SEL("top.mid.number");
+ SEL("top.mid.array");
+ SEL("top.number");
+ SEL("top.array");
+ SEL("top.array[0]");
+ SEL("top.array[1]");
+ SEL("top.array[2]");
+ SEL("top.array[2].a");
+ SEL("top.array[2].b");
+ SEL("top.array[2].bb");
+ SEL("top.array[2].bb[0]");
+ SEL("top.array[2].bb[1]");
+ SEL("top.array[2].bb[2]");
+ SEL("top.array[2].bb[3]");
+ SEL("top.array[2].bb[3].x");
+ SEL("top.array[2].bb[3].x.nofurther");
+ SEL("top.array[2].bb[4]");
+ SEL("top.array[3]");
+
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d.out
new file mode 100644
index 0000000..a857ab9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.general.d.out
@@ -0,0 +1,218 @@
+
+tst |empty array|
+in |[]|
+sel |0|
+out |<NULL>|
+
+tst |one-element array: integer|
+in |[1]|
+sel |0|
+out |1|
+sel |1|
+out |<NULL>|
+sel |100|
+out |<NULL>|
+sel |-1|
+out |<NULL>|
+
+tst |one-element array: hex integer (not in spec, not supported)|
+in |[0x1000]|
+sel |0|
+out |<NULL>|
+
+tst |one-element array: float|
+in |[1.5001]|
+sel |0|
+out |1.5001|
+
+tst |one-element array: float + exponent|
+in |[16.3e10]|
+sel |0|
+out |16.3e10|
+
+tst |one-element array: integer + whitespace|
+in |[ 5 ]|
+sel |0|
+out |5|
+
+tst |one-element array: integer + exponent + whitespace|
+in |[ 16E10 ]|
+sel |0|
+out |16E10|
+
+tst |one-element array: string|
+in |["alpha"]|
+sel |0|
+out |alpha|
+
+tst |alternative first-element indexing|
+in |[1,5,10,15,20]|
+sel |[0]|
+out |1|
+sel |[3]|
+out |15|
+sel |[4]|
+out |20|
+sel |[5]|
+out |<NULL>|
+
+tst |one-element array: object|
+in |[ { "first": true, "second": false }]|
+sel |0.first|
+out |true|
+sel |0.second|
+out |false|
+sel |0.third|
+out |<NULL>|
+
+tst |many-element array: integers|
+in |[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]|
+sel |10|
+out |55|
+sel |14|
+out |377|
+sel |19|
+out |<NULL>|
+
+tst |many-element array: multiple types|
+in |["string",32,true,{"a":9,"b":false},100.3e10,false,200.5,{"key":"val"},null]|
+sel |0|
+out |string|
+sel |0.notobject|
+out |<NULL>|
+sel |1|
+out |32|
+sel |2|
+out |true|
+sel |3|
+out |{"a":9,"b":false}|
+sel |3.a|
+out |9|
+sel |3.b|
+out |false|
+sel |3.c|
+out |<NULL>|
+sel |4|
+out |100.3e10|
+sel |5|
+out |false|
+sel |6|
+out |200.5|
+sel |7|
+out |{"key":"val"}|
+sel |7.key|
+out |val|
+sel |7.key.notobject|
+out |<NULL>|
+sel |7.nonexist|
+out |<NULL>|
+sel |8|
+out |null|
+sel |9|
+out |<NULL>|
+
+tst |many-element array: multiple types + whitespace|
+in |
+[ "string" , 32 , true , {"a": 9, "b": false}, 100.3e10, false, 200.5,{"key" :
+ "val"}, null ] |
+sel |0|
+out |string|
+sel |0.notobject|
+out |<NULL>|
+sel |1|
+out |32|
+sel |2|
+out |true|
+sel |3|
+out |{"a": 9, "b": false}|
+sel |3.a|
+out |9|
+sel |3.b|
+out |false|
+sel |3.c|
+out |<NULL>|
+sel |4|
+out |100.3e10|
+sel |5|
+out |false|
+sel |6|
+out |200.5|
+sel |7|
+out |{"key" :
+ "val"}|
+sel |7.key|
+out |val|
+sel |7.key.notobject|
+out |<NULL>|
+sel |7.nonexist|
+out |<NULL>|
+sel |8|
+out |null|
+sel |9|
+out |<NULL>|
+
+tst |two-element array: various string escape codes|
+in |["abcd \" \\ \/ \b \f \n \r \t \u0000 \uf00F ", "final"]|
+sel |0|
+out |abcd \" \\ \/ \b \f \n \r \t \u0000 \uf00F |
+sel |1|
+out |final|
+
+tst |three-element array: broken escape code|
+in |["fine here", "dodgey \u00AZ", "wont get here"]|
+sel |0|
+out |fine here|
+sel |1|
+out |<NULL>|
+sel |2|
+out |<NULL>|
+
+tst |nested objects|
+in |{ "top": { "mid" : { "legs": "feet" }, "number": 9, "array":[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]}}|
+sel |top|
+out |{ "mid" : { "legs": "feet" }, "number": 9, "array":[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]}|
+sel |fargo|
+out |<NULL>|
+sel |top.mid|
+out |{ "legs": "feet" }|
+sel |top.centre|
+out |<NULL>|
+sel |top.mid.legs|
+out |feet|
+sel |top.mid.number|
+out |<NULL>|
+sel |top.mid.array|
+out |<NULL>|
+sel |top.number|
+out |9|
+sel |top.array|
+out |[0,1,{"a":true,"bb":[1,2,false,{"x":"yz"}]}]|
+sel |top.array[0]|
+out |0|
+sel |top.array[1]|
+out |1|
+sel |top.array[2]|
+out |{"a":true,"bb":[1,2,false,{"x":"yz"}]}|
+sel |top.array[2].a|
+out |true|
+sel |top.array[2].b|
+out |<NULL>|
+sel |top.array[2].bb|
+out |[1,2,false,{"x":"yz"}]|
+sel |top.array[2].bb[0]|
+out |1|
+sel |top.array[2].bb[1]|
+out |2|
+sel |top.array[2].bb[2]|
+out |false|
+sel |top.array[2].bb[3]|
+out |{"x":"yz"}|
+sel |top.array[2].bb[3].x|
+out |yz|
+sel |top.array[2].bb[3].x.nofurther|
+out |<NULL>|
+sel |top.array[2].bb[4]|
+out |<NULL>|
+sel |top.array[3]|
+out |<NULL>|
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d
new file mode 100644
index 0000000..6aa50b9
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d
@@ -0,0 +1,51 @@
+/*
+ * 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, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * ASSERTION:
+ * json() run time must be bounded above by strsize. This test makes strsize
+ * small and deliberately overflows it to prove we bail and return NULL in
+ * the event that we run off the end of the string.
+ *
+ */
+
+#pragma D option quiet
+#pragma D option strsize=18
+
+BEGIN
+{
+ in = "{\"a\": 1024}"; /* length == 19 */
+ out = json(in, "a");
+ printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
+
+ in = "{\"a\": 1024}"; /* length == 11 */
+ out = json(in, "a");
+ printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
+
+ in = "{\"a\":false,\"b\":true}"; /* length == 20 */
+ out = json(in, "b");
+ printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
+
+ in = "{\"a\":false,\"b\":20}"; /* length == 18 */
+ out = json(in, "b");
+ printf("|%s|\n%s\n\n", in, out != NULL ? out : "<NULL>");
+
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d.out
new file mode 100644
index 0000000..7f1d79b
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.strsize.d.out
@@ -0,0 +1,13 @@
+|{"a": 1024|
+<NULL>
+
+|{"a": 1024}|
+1024
+
+|{"a":false,"b":tru|
+<NULL>
+
+|{"a":false,"b":20}|
+20
+
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.c
new file mode 100644
index 0000000..307106d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.c
@@ -0,0 +1,61 @@
+/*
+ * 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 (c), Joyent, Inc. All rights reserved.
+ */
+
+#include <sys/sdt.h>
+#include "usdt.h"
+
+#define FMT "{" \
+ " \"sizes\": [ \"first\", 2, %f ]," \
+ " \"index\": %d," \
+ " \"facts\": {" \
+ " \"odd\": \"%s\"," \
+ " \"even\": \"%s\"" \
+ " }," \
+ " \"action\": \"%s\"" \
+ "}\n"
+
+int
+waiting(volatile int *a)
+{
+ return (*a);
+}
+
+int
+main(int argc, char **argv)
+{
+ volatile int a = 0;
+ int idx;
+ double size = 250.5;
+
+ while (waiting(&a) == 0)
+ continue;
+
+ for (idx = 0; idx < 10; idx++) {
+ char *odd, *even, *json, *action;
+
+ size *= 1.78;
+ odd = idx % 2 == 1 ? "true" : "false";
+ even = idx % 2 == 0 ? "true" : "false";
+ action = idx == 7 ? "ignore" : "print";
+
+ asprintf(&json, FMT, size, idx, odd, even, action);
+ BUNYAN_FAKE_LOG_DEBUG(json);
+ free(json);
+ }
+
+ BUNYAN_FAKE_LOG_DEBUG("{\"finished\": true}");
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d
new file mode 100644
index 0000000..f0fbdd5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d
@@ -0,0 +1,65 @@
+/*
+ * 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 (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option strsize=4k
+#pragma D option quiet
+#pragma D option destructive
+
+/*
+ * This test reads a JSON string from a USDT probe, roughly simulating the
+ * primary motivating use case for the json() subroutine: filtering
+ * JSON-formatted log messages from a logging subsystem like node-bunyan.
+ */
+
+pid$1:a.out:waiting:entry
+{
+ this->value = (int *)alloca(sizeof (int));
+ *this->value = 1;
+ copyout(this->value, arg0, sizeof (int));
+}
+
+bunyan*$1:::log-*
+{
+ this->j = copyinstr(arg0);
+}
+
+bunyan*$1:::log-*
+/json(this->j, "finished") == NULL && json(this->j, "action") != "ignore"/
+{
+ this->index = strtoll(json(this->j, "index"));
+ this->size = json(this->j, "sizes[2]");
+ this->odd = json(this->j, "facts.odd");
+ this->even = json(this->j, "facts.even");
+ printf("[%d] sz %s odd %s even %s\n", this->index, this->size,
+ this->odd, this->even);
+}
+
+bunyan*$1:::log-*
+/json(this->j, "finished") != NULL/
+{
+ printf("FINISHED!\n");
+ exit(0);
+}
+
+tick-10s
+{
+ printf("ERROR: Timed out before finish message!\n");
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d.out
new file mode 100644
index 0000000..c7f58bb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/tst.usdt.d.out
@@ -0,0 +1,11 @@
+[0] sz 445.890000 odd false even true
+[1] sz 793.684200 odd true even false
+[2] sz 1412.757876 odd false even true
+[3] sz 2514.709019 odd true even false
+[4] sz 4476.182054 odd false even true
+[5] sz 7967.604057 odd true even false
+[6] sz 14182.335221 odd false even true
+[8] sz 44935.310914 odd false even true
+[9] sz 79984.853427 odd true even false
+FINISHED!
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/usdt.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/usdt.d
new file mode 100644
index 0000000..1a4fc87
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/json/usdt.d
@@ -0,0 +1,27 @@
+/*
+ * 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, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * Sets up a fake node-bunyan-like USDT provider for use from C.
+ */
+
+provider bunyan_fake {
+ probe log__trace(char *msg);
+ probe log__debug(char *msg);
+ probe log__info(char *msg);
+ probe log__warn(char *msg);
+ probe log__error(char *msg);
+ probe log__fatal(char *msg);
+};
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.fds.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.fds.ksh
new file mode 100644
index 0000000..a5aa271
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.fds.ksh
@@ -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 (c) 2012, Joyent, Inc. All rights reserved.
+#
+
+tmpin=/tmp/tst.fds.$$.d
+tmpout1=/tmp/tst.fds.$$.out1
+tmpout2=/tmp/tst.fds.$$.out2
+
+cat > $tmpin <<EOF
+#define DUMPFIELD(fd, fmt, field) \
+ errmsg = "could not dump field"; \
+ printf("%d: field =fmt\n", fd, fds[fd].field);
+
+/*
+ * Note that we are explicitly not looking at fi_mount -- it (by design) does
+ * not work if not running with kernel permissions.
+ */
+#define DUMP(fd) \
+ DUMPFIELD(fd, %s, fi_name); \
+ DUMPFIELD(fd, %s, fi_dirname); \
+ DUMPFIELD(fd, %s, fi_pathname); \
+ DUMPFIELD(fd, %d, fi_offset); \
+ DUMPFIELD(fd, %s, fi_fs); \
+ DUMPFIELD(fd, %o, fi_oflags);
+
+BEGIN
+{
+ DUMP(0);
+ DUMP(1);
+ DUMP(2);
+ DUMP(3);
+ DUMP(4);
+ exit(0);
+}
+
+ERROR
+{
+ printf("error: %s\n", errmsg);
+ exit(1);
+}
+EOF
+
+#
+# First, with all privs
+#
+/usr/sbin/dtrace -q -Cs /dev/stdin < $tmpin > $tmpout2
+mv $tmpout2 $tmpout1
+
+#
+# And now with only dtrace_proc and dtrace_user -- the output should be
+# identical.
+#
+ppriv -s A=basic,dtrace_proc,dtrace_user $$
+
+/usr/sbin/dtrace -q -Cs /dev/stdin < $tmpin > $tmpout2
+
+echo ">>> $tmpout1"
+cat $tmpout1
+
+echo ">>> $tmpout2"
+cat $tmpout2
+
+rval=0
+
+if ! cmp $tmpout1 $tmpout2 ; then
+ rval=1
+fi
+
+rm $tmpout1 $tmpout2 $tmpin
+exit $rval
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
index ae4934c..da9bb4c 100644
--- 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
@@ -22,8 +22,8 @@
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright (c) 2012, Joyent, Inc. All rights reserved.
#
-#ident "%Z%%M% %I% %E% SMI"
ppriv -s A=basic,dtrace_proc,dtrace_user $$
@@ -31,7 +31,7 @@ ppriv -s A=basic,dtrace_proc,dtrace_user $$
BEGIN {
errorcount = 0;
- expected_errorcount = 23;
+ expected_errorcount = 27;
}
BEGIN { trace(mutex_owned(&`pidlock)); }
@@ -55,6 +55,8 @@ BEGIN { trace(strtok(`initname, "/")); }
BEGIN { trace(strtok(NULL, "/")); }
BEGIN { trace(strtok("foo/bar", `initname)); }
BEGIN { trace(strtok(NULL, `initname)); }
+BEGIN { trace(strtoll(`initname)); }
+BEGIN { trace(strtoll(`initname, 10)); }
BEGIN { trace(substr(`initname, 2, 3)); }
BEGIN { trace(ddi_pathname(`top_devinfo, 1)); }
@@ -63,6 +65,9 @@ BEGIN { trace(strjoin("foo", `initname)); }
BEGIN { trace(dirname(`initname)); }
BEGIN { trace(cleanpath(`initname)); }
+BEGIN { j = "{\"/sbin/init\":\"uh oh\"}"; trace(json(j, `initname)); }
+BEGIN { trace(json(`initname, "x")); }
+
ERROR {
errorcount++;
}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.getf.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.getf.ksh
new file mode 100644
index 0000000..7dbb83f
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.getf.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 (c) 2012, Joyent, Inc. All rights reserved.
+#
+
+ppriv -s A=basic,dtrace_proc,dtrace_user $$
+
+/usr/sbin/dtrace -q -Cs /dev/stdin <<EOF
+
+#define CANREAD(field) \
+ BEGIN { this->fp = getf(0); errmsg = "can't read field"; \
+ printf("field: "); trace(this->fp->field); printf("\n"); }
+
+#define CANTREAD(field) \
+ BEGIN { errmsg = ""; this->fp = getf(0); trace(this->fp->field); \
+ printf("\nable to successfully read field!"); exit(1); }
+
+CANREAD(f_flag)
+CANREAD(f_flag2)
+CANREAD(f_vnode)
+CANREAD(f_offset)
+CANREAD(f_cred)
+CANREAD(f_audit_data)
+CANREAD(f_count)
+
+/*
+ * We can potentially read parts of our cred, but we can't dereference
+ * through cr_zone.
+ */
+CANTREAD(f_cred->cr_zone->zone_id)
+
+CANREAD(f_vnode->v_path)
+CANREAD(f_vnode->v_op)
+CANREAD(f_vnode->v_op->vnop_name)
+
+CANTREAD(f_vnode->v_flag)
+CANTREAD(f_vnode->v_count)
+CANTREAD(f_vnode->v_pages)
+CANTREAD(f_vnode->v_type)
+CANTREAD(f_vnode->v_vfsmountedhere)
+CANTREAD(f_vnode->v_op->vop_open)
+
+BEGIN
+{
+ errmsg = "";
+ this->fp = getf(0);
+ this->fp2 = getf(1);
+
+ trace(this->fp->f_vnode);
+ printf("\nable to successfully read this->fp!");
+ exit(1);
+}
+
+BEGIN
+{
+ errmsg = "";
+ this->fp = getf(0);
+}
+
+BEGIN
+{
+ trace(this->fp->f_vnode);
+ printf("\nable to successfully read this->fp from prior clause!");
+}
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+/errmsg != ""/
+{
+ printf("fatal error: %s", errmsg);
+ exit(1);
+}
+
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.procpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.procpriv.ksh
new file mode 100644
index 0000000..7022566
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.procpriv.ksh
@@ -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 (c) 2012, Joyent, Inc. All rights reserved.
+#
+
+ppriv -s A=basic,dtrace_proc,dtrace_user $$
+
+#
+# When we have dtrace_proc (but lack dtrace_kernel), we expect to be able to
+# read certain curpsinfo/curlwpsinfo/curcpu fields even though they require
+# reading in-kernel state. However, there are other fields in these translated
+# structures that we know we shouldn't be able to read, as they require reading
+# in-kernel state that we cannot read with only dtrace_proc. Finally, there
+# are a few fields that we may or may not be able to read depending on the
+# specifics of context. This test therefore asserts that we can read what we
+# think we should be able to, that we can't read what we think we shouldn't be
+# able to, and (for purposes of completeness) that we are indifferent about
+# what we cannot assert one way or the other.
+#
+/usr/sbin/dtrace -q -Cs /dev/stdin <<EOF
+
+#define CANREAD(what, field) \
+ BEGIN { errmsg = "can't read field from what"; printf("field: "); \
+ trace(what->field); printf("\n"); }
+
+#define CANTREAD(what, field) \
+ BEGIN { errmsg = ""; trace(what->field); \
+ printf("\nable to successfully read field from what!"); exit(1); }
+
+#define MIGHTREAD(what, field) \
+ BEGIN { errmsg = ""; printf("field: "); trace(what->field); printf("\n"); }
+
+#define CANREADVAR(vname) \
+ BEGIN { errmsg = "can't read vname"; printf("vname: "); \
+ trace(vname); printf("\n"); }
+
+#define CANTREADVAR(vname) \
+ BEGIN { errmsg = ""; trace(vname); \
+ printf("\nable to successfully read vname!"); exit(1); }
+
+#define MIGHTREADVAR(vname) \
+ BEGIN { errmsg = ""; printf("vname: "); trace(vname); printf("\n"); }
+
+CANREAD(curpsinfo, pr_pid)
+CANREAD(curpsinfo, pr_nlwp)
+CANREAD(curpsinfo, pr_ppid)
+CANREAD(curpsinfo, pr_uid)
+CANREAD(curpsinfo, pr_euid)
+CANREAD(curpsinfo, pr_gid)
+CANREAD(curpsinfo, pr_egid)
+CANREAD(curpsinfo, pr_addr)
+CANREAD(curpsinfo, pr_start)
+CANREAD(curpsinfo, pr_fname)
+CANREAD(curpsinfo, pr_psargs)
+CANREAD(curpsinfo, pr_argc)
+CANREAD(curpsinfo, pr_argv)
+CANREAD(curpsinfo, pr_envp)
+CANREAD(curpsinfo, pr_dmodel)
+
+/*
+ * If our p_pgidp points to the same pid structure as our p_pidp, we will
+ * be able to read pr_pgid -- but we won't if not.
+ */
+MIGHTREAD(curpsinfo, pr_pgid)
+
+CANTREAD(curpsinfo, pr_sid)
+CANTREAD(curpsinfo, pr_ttydev)
+CANTREAD(curpsinfo, pr_projid)
+CANTREAD(curpsinfo, pr_zoneid)
+CANTREAD(curpsinfo, pr_contract)
+
+CANREAD(curlwpsinfo, pr_flag)
+CANREAD(curlwpsinfo, pr_lwpid)
+CANREAD(curlwpsinfo, pr_addr)
+CANREAD(curlwpsinfo, pr_wchan)
+CANREAD(curlwpsinfo, pr_stype)
+CANREAD(curlwpsinfo, pr_state)
+CANREAD(curlwpsinfo, pr_sname)
+CANREAD(curlwpsinfo, pr_syscall)
+CANREAD(curlwpsinfo, pr_pri)
+CANREAD(curlwpsinfo, pr_onpro)
+CANREAD(curlwpsinfo, pr_bindpro)
+CANREAD(curlwpsinfo, pr_bindpset)
+
+CANTREAD(curlwpsinfo, pr_clname)
+CANTREAD(curlwpsinfo, pr_lgrp)
+
+CANREAD(curcpu, cpu_id)
+
+CANTREAD(curcpu, cpu_pset)
+CANTREAD(curcpu, cpu_chip)
+CANTREAD(curcpu, cpu_lgrp)
+CANTREAD(curcpu, cpu_info)
+
+/*
+ * We cannot assert one thing or another about the variable "root": for those
+ * with only dtrace_proc, it will be readable in the global but not readable in
+ * the non-global.
+ */
+MIGHTREADVAR(root)
+
+CANREADVAR(cpu)
+CANTREADVAR(pset)
+CANTREADVAR(cwd)
+CANTREADVAR(chip)
+CANTREADVAR(lgrp)
+
+BEGIN
+{
+ exit(0);
+}
+
+ERROR
+/errmsg != ""/
+{
+ printf("fatal error: %s", errmsg);
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.providers.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.providers.ksh
new file mode 100644
index 0000000..94c3722
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/privs/tst.providers.ksh
@@ -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 (c) 2012, Joyent, Inc. All rights reserved.
+#
+
+#
+# First, make sure that we can successfully enable the io provider
+#
+if ! dtrace -P io -n BEGIN'{exit(0)}' > /dev/null 2>&1 ; then
+ echo failed to enable io provider with full privs
+ exit 1
+fi
+
+ppriv -s A=basic,dtrace_proc,dtrace_user $$
+
+#
+# Now make sure that we cannot enable the io provider with reduced privs
+#
+if ! dtrace -x errtags -P io -n BEGIN'{exit(1)}' 2>&1 | \
+ grep D_PDESC_ZERO > /dev/null 2>&1 ; then
+ echo successfully enabled the io provider with reduced privs
+ exit 1
+fi
+
+#
+# Keeping our reduced privs, we want to assure that we can see every provider
+# that we think we should be able to see -- and that we can see curpsinfo
+# state but can't otherwise see arguments.
+#
+/usr/sbin/dtrace -wq -Cs /dev/stdin <<EOF
+
+int seen[string];
+int err;
+
+#define CANENABLE(provider) \
+provider::: \
+/err == 0 && progenyof(\$pid) && !seen["provider"]/ \
+{ \
+ trace(arg0); \
+ printf("\nsuccessful trace of arg0 in %s:%s:%s:%s\n", \
+ probeprov, probemod, probefunc, probename); \
+ exit(++err); \
+} \
+ \
+provider::: \
+/progenyof(\$pid)/ \
+{ \
+ seen["provider"]++; \
+} \
+ \
+provider::: \
+/progenyof(\$pid)/ \
+{ \
+ errstr = "provider"; \
+ this->ignore = stringof(curpsinfo->pr_psargs); \
+ errstr = ""; \
+} \
+ \
+END \
+/err == 0 && !seen["provider"]/ \
+{ \
+ printf("no probes from provider\n"); \
+ exit(++err); \
+} \
+ \
+END \
+/err == 0/ \
+{ \
+ printf("saw %d probes from provider\n", seen["provider"]); \
+}
+
+CANENABLE(proc)
+CANENABLE(sched)
+CANENABLE(vminfo)
+CANENABLE(sysinfo)
+
+BEGIN
+{
+ /*
+ * We'll kick off a system of a do-nothing command -- which should be
+ * enough to kick proc, sched, vminfo and sysinfo probes.
+ */
+ system("echo > /dev/null");
+}
+
+ERROR
+/err == 0 && errstr != ""/
+{
+ printf("fatal error: couldn't read curpsinfo->pr_psargs in ");
+ printf("%s-provided probe\n", errstr);
+ exit(++err);
+}
+
+proc:::exit
+/progenyof(\$pid)/
+{
+ exit(0);
+}
+
+tick-10ms
+/i++ > 500/
+{
+ printf("exit probe did not seem to fire\n");
+ exit(++err);
+}
+EOF
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d
new file mode 100644
index 0000000..4d6b5af
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooLarge.d
@@ -0,0 +1,35 @@
+/*
+ * 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 (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * ASSERTION:
+ * The largest base we will accept is Base 36 -- i.e. using all of 0-9 and
+ * A-Z as numerals.
+ *
+ * SECTION: Actions and Subroutines/strtoll()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%d\n", strtoll("0", 37));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d
new file mode 100644
index 0000000..de56b50
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/err.BaseTooSmall.d
@@ -0,0 +1,34 @@
+/*
+ * 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 (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * ASSERTION:
+ * The smallest base we will accept is Base 2.
+ *
+ * SECTION: Actions and Subroutines/strtoll()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%d\n", strtoll("0", 1));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d
new file mode 100644
index 0000000..0b1812a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d
@@ -0,0 +1,66 @@
+/*
+ * 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 (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * ASSERTION:
+ * Test the strtoll() subroutine.
+ *
+ * SECTION: Actions and Subroutines/strtoll()
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+
+ /* minimum base (2) and maximum base (36): */
+ printf("%d\n", strtoll("0", 2));
+ printf("%d\n", strtoll("1", 36));
+
+ /* simple tests: */
+ printf("%d\n", strtoll("0x20", 16));
+ printf("%d\n", strtoll("-32", 10));
+ printf("%d\n", strtoll("010", 8));
+ printf("%d\n", strtoll("101010", 2));
+
+ /* INT64_MIN and INT64_MAX: */
+ printf("%d\n", strtoll("9223372036854775807"));
+ printf("%d\n", strtoll("-9223372036854775808"));
+ printf("%d\n", strtoll("0777777777777777777777", 8));
+ printf("%d\n", strtoll("-01000000000000000000000", 8));
+
+ /* wrapping: */
+ printf("%d\n", strtoll("1000000000000000000000", 8));
+ printf("%d\n", strtoll("-1000000000000000000001", 8));
+
+ /* hex without prefix: */
+ printf("%d\n", strtoll("baddcafe", 16));
+
+ /* stopping at first out-of-base character: */
+ printf("%d\n", strtoll("12j", 10));
+ printf("%d\n", strtoll("102", 2));
+
+ /* base 36: */
+ printf("%d\n", strtoll("-0DTrace4EverZ", 36));
+
+ /* base 10 is assumed: */
+ printf("%d\n", strtoll("1985"));
+ printf("%d\n", strtoll("-2012"));
+
+ /* empty string: */
+ printf("%d\n", strtoll(""));
+
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out
new file mode 100644
index 0000000..d12eb9c
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/strtoll/tst.strtoll.d.out
@@ -0,0 +1,20 @@
+0
+1
+32
+-32
+8
+42
+9223372036854775807
+-9223372036854775808
+9223372036854775807
+-9223372036854775808
+-9223372036854775808
+9223372036854775807
+3135097598
+12
+2
+-1819882045752187535
+1985
+-2012
+0
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d
new file mode 100644
index 0000000..4865d81
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d
@@ -0,0 +1,21 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ trace((pidfoo`int)0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d
new file mode 100644
index 0000000..bafed12
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d
@@ -0,0 +1,21 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ trace((pid8foo`int)0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d
new file mode 100644
index 0000000..fb9443a
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d
@@ -0,0 +1,21 @@
+/*
+ * 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 (c) 2013 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ trace((pid0`int)0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh
new file mode 100644
index 0000000..978cde3
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh
@@ -0,0 +1,34 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# While it's hard to be completely certain that a type of the name we want
+# doesn't exist, we're going to try to pick a name which is rather unique.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="season_8_mountain_of_madness_t"
+pid=$$
+
+rc=`$dtrace -n "BEGIN{ trace(pid$pid`$t)0); }"`
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh
new file mode 100644
index 0000000..e64ed52
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh
@@ -0,0 +1,35 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# While it's hard to be completely certain that a type of the name we want
+# doesn't exist, we're going to try to pick a name which is rather
+# unique. This time we're also going to use the pid$target alias.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="season_8_mountain_of_madness_t"
+pid=$$
+
+rc=`$dtrace -n "BEGIN{ trace(pid`$t)0); }"` -p $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh
new file mode 100644
index 0000000..d987c8d
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh
@@ -0,0 +1,90 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# This test is purposefully using a 64-bit DTrace and thus 64-bit types
+# when compared with a 32-bit process. This test uses the userland
+# keyword and so the implicit copyin should access illegal memory and
+# thus exit.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="zelda_info_t"
+exe="tst.chasestrings.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -64 -qs /dev/stdin <<EOF
+typedef struct info {
+ char *zi_gamename;
+ int zi_ndungeons;
+ char *zi_villain;
+ int zi_haszelda;
+} info_t;
+
+pid$pid::has_princess:entry
+/next == 0/
+{
+ this->t = (userland info_t *)arg0;
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(this->t->zi_gamename), this->t->zi_ndungeons,
+ stringof(this->t->zi_villain), this->t->zi_haszelda);
+ next = 1;
+}
+
+pid$pid::has_dungeons:entry
+/next == 1/
+{
+ this->t = (userland info_t *)arg0;
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(this->t->zi_gamename), this->t->zi_ndungeons,
+ stringof(this->t->zi_villain), this->t->zi_haszelda);
+ next = 2;
+}
+
+pid$pid::has_villain:entry
+/next == 2/
+{
+ this->t = (userland info_t *)arg0;
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(this->t->zi_gamename), this->t->zi_ndungeons,
+ stringof(this->t->zi_villain), this->t->zi_haszelda);
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c
new file mode 100644
index 0000000..a4d25f8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c
@@ -0,0 +1,46 @@
+/*
+ * 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 2013 (c) Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * This test tries to make sure that we have CTF data for a type that only this
+ * binary would reasonably have. In this case, the
+ * season_7_lisa_the_vegetarian_t.
+ */
+#include <unistd.h>
+
+typedef struct season_7_lisa_the_vegetarian {
+ int fr_salad;
+} season_7_lisa_the_vegetarian_t;
+
+int
+sleeper(season_7_lisa_the_vegetarian_t *lp)
+{
+ for (;;) {
+ sleep(lp->fr_salad);
+ }
+ /*NOTREACHED*/
+ return (0);
+}
+
+int
+main(void)
+{
+ season_7_lisa_the_vegetarian_t l;
+ l.fr_salad = 100;
+
+ sleeper(&l);
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh
new file mode 100644
index 0000000..151a936
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh
@@ -0,0 +1,44 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# Lookup a type that is inside a.out.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="season_7_lisa_the_vegetrian_t *"
+exe="tst.aouttype.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+rc=`$dtrace -n "BEGIN{ trace((pid$pid\`$t)0); exit(0); }"`
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c
new file mode 100644
index 0000000..595a7cb
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c
@@ -0,0 +1,79 @@
+/*
+ * 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 2013 (c) Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * This test takes data from the current binary which is basically running in a
+ * loop between two functions and our goal is to have two unique types that they
+ * contain which we can print.
+ */
+
+#include <unistd.h>
+
+typedef struct zelda_info {
+ char *zi_gamename;
+ int zi_ndungeons;
+ char *zi_villain;
+ int zi_haszelda;
+} zelda_info_t;
+
+static int
+has_princess(zelda_info_t *z)
+{
+ return (z->zi_haszelda);
+}
+
+static int
+has_dungeons(zelda_info_t *z)
+{
+ return (z->zi_ndungeons != 0);
+}
+
+static const char *
+has_villain(zelda_info_t *z)
+{
+ return (z->zi_villain);
+}
+
+int
+main(void)
+{
+ zelda_info_t oot;
+ zelda_info_t la;
+ zelda_info_t lttp;
+
+ oot.zi_gamename = "Ocarina of Time";
+ oot.zi_ndungeons = 10;
+ oot.zi_villain = "Ganondorf";
+ oot.zi_haszelda = 1;
+
+ la.zi_gamename = "Link's Awakening";
+ la.zi_ndungeons = 9;
+ la.zi_villain = "Nightmare";
+ la.zi_haszelda = 0;
+
+ lttp.zi_gamename = "A Link to the Past";
+ lttp.zi_ndungeons = 12;
+ lttp.zi_villain = "Ganon";
+ lttp.zi_haszelda = 1;
+
+ for (;;) {
+ (void) has_princess(&oot);
+ (void) has_dungeons(&la);
+ (void) has_villain(&lttp);
+ sleep(1);
+ }
+
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh
new file mode 100644
index 0000000..2502846
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh
@@ -0,0 +1,76 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# This test is checking that we can read members and that pointers inside
+# members point to valid data that is intelligible, eg. strings.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="zelda_info_t"
+exe="tst.chasestrings.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -qs /dev/stdin <<EOF
+pid$pid::has_princess:entry
+/next == 0/
+{
+ this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)));
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons,
+ copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda);
+ next = 1;
+}
+
+pid$pid::has_dungeons:entry
+/next == 1/
+{
+ this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)));
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons,
+ copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda);
+ next = 2;
+}
+
+pid$pid::has_villain:entry
+/next == 2/
+{
+ this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)));
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons,
+ copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda);
+ exit(0);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out
new file mode 100644
index 0000000..219e406
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out
@@ -0,0 +1,4 @@
+game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1
+game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0
+game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.c
new file mode 100644
index 0000000..916a5b5
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.c
@@ -0,0 +1,29 @@
+/*
+ * 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 2013 (c) Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * We're linked against libc which has types, though we do not.
+ */
+#include <unistd.h>
+
+int
+main(void)
+{
+ for (;;) {
+ sleep(1000);
+ }
+ /*NOTREACHED*/
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh
new file mode 100644
index 0000000..af7c6c8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh
@@ -0,0 +1,45 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# Here we want to make sure that the program in question does not have ctf data
+# in its a.out; however, we can get types out of a linked libc.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="int"
+exe="tst.libtype.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -eq 0 ]]; then
+ echo "CTF exists in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+rc=`$dtrace -n "BEGIN{ trace((pid$pid\`$t)0); exit(0); }"`
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh
new file mode 100644
index 0000000..f767def
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh
@@ -0,0 +1,44 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# We should be able to see both strstr from libc and from ld on an
+# alternate linkmap.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+$dtrace -q -p $$ -s /dev/stdin <<EOF
+pid\$target:LM1\`ld.so.1:strstr:entry,
+pid\$target:libc.so.1:strstr:entry
+{
+ exit (0);
+}
+
+BEGIN
+{
+ exit (0);
+}
+EOF
+rc=$?
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh
new file mode 100644
index 0000000..febb015
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh
@@ -0,0 +1,69 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# Use print() on userland CTF types and verify we get the data we expect.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="final_fantasy_info_t"
+exe="tst.printtype.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -qs /dev/stdin <<EOF
+pid$pid::ff_getgameid:entry
+/next == 0/
+{
+ print(*args[0]);
+ printf("\n");
+ next = 1;
+}
+
+pid$pid::ff_getpartysize:entry
+/next == 1/
+{
+ print(*args[0]);
+ printf("\n");
+ next = 2;
+}
+
+pid$pid::ff_getsummons:entry
+/next == 2/
+{
+ print(*args[0]);
+ printf("\n");
+ exit(0);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh
new file mode 100644
index 0000000..7398dc4
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh
@@ -0,0 +1,70 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# Use print() on userland CTF types and verify we get the data we
+# expect. This time, use $target to make sure that path works correctly.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="final_fantasy_info_t"
+exe="tst.printtype.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -p $pid -qs /dev/stdin <<EOF
+pid\$target::ff_getgameid:entry
+/next == 0/
+{
+ print(*args[0]);
+ printf("\n");
+ next = 1;
+}
+
+pid\$target::ff_getpartysize:entry
+/next == 1/
+{
+ print(*args[0]);
+ printf("\n");
+ next = 2;
+}
+
+pid\$target::ff_getsummons:entry
+/next == 2/
+{
+ print(*args[0]);
+ printf("\n");
+ exit(0);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.c
new file mode 100644
index 0000000..6c27593
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.c
@@ -0,0 +1,72 @@
+/*
+ * 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 2013 (c) Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * The point of this is to use print() on various functions to make sure that we
+ * can print basic structures. Note that we purposefully are making sure that
+ * there are no pointers here.
+ */
+#include <unistd.h>
+
+typedef struct final_fantasy_info {
+ int ff_gameid;
+ int ff_partysize;
+ int ff_hassummons;
+} final_fantasy_info_t;
+
+static int
+ff_getgameid(final_fantasy_info_t *f)
+{
+ return (0);
+}
+
+static int
+ff_getpartysize(final_fantasy_info_t *f)
+{
+ return (0);
+}
+
+static int
+ff_getsummons(final_fantasy_info_t *f)
+{
+ return (0);
+}
+
+int
+main(void)
+{
+ final_fantasy_info_t ffiii, ffx, ffi;
+
+ ffi.ff_gameid = 1;
+ ffi.ff_partysize = 4;
+ ffi.ff_hassummons = 0;
+
+ ffiii.ff_gameid = 6;
+ ffiii.ff_partysize = 4;
+ ffiii.ff_hassummons = 1;
+
+ ffx.ff_gameid = 10;
+ ffx.ff_partysize = 3;
+ ffx.ff_hassummons = 1;
+
+ for (;;) {
+ ff_getgameid(&ffi);
+ ff_getpartysize(&ffx);
+ ff_getsummons(&ffiii);
+ sleep(1);
+ }
+ /*NOTREACHED*/
+ return (0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh
new file mode 100644
index 0000000..dfc1535
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh
@@ -0,0 +1,69 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# Use print() on userland CTF types and verify we get the data we expect.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="final_fantasy_info_t"
+exe="tst.printtype.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -qs /dev/stdin <<EOF
+pid$pid::ff_getgameid:entry
+/next == 0/
+{
+ print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))));
+ printf("\n");
+ next = 1;
+}
+
+pid$pid::ff_getpartysize:entry
+/next == 1/
+{
+ print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))));
+ printf("\n");
+ next = 2;
+}
+
+pid$pid::ff_getsummons:entry
+/next == 2/
+{
+ print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))));
+ printf("\n");
+ exit(0);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out
new file mode 100644
index 0000000..1770ba2
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out
@@ -0,0 +1,16 @@
+final_fantasy_info_t {
+ int ff_gameid = 0x1
+ int ff_partysize = 0x4
+ int ff_hassummons = 0
+}
+final_fantasy_info_t {
+ int ff_gameid = 0xa
+ int ff_partysize = 0x3
+ int ff_hassummons = 0x1
+}
+final_fantasy_info_t {
+ int ff_gameid = 0x6
+ int ff_partysize = 0x4
+ int ff_hassummons = 0x1
+}
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh
new file mode 100644
index 0000000..025d4a8
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh
@@ -0,0 +1,70 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# Use print() on userland CTF types and verify we get the data we
+# expect. Use the pid` alias for $target.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="final_fantasy_info_t"
+exe="tst.printtype.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -p $pid -qs /dev/stdin <<EOF
+pid\$target::ff_getgameid:entry
+/next == 0/
+{
+ print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t))));
+ printf("\n");
+ next = 1;
+}
+
+pid\$target::ff_getpartysize:entry
+/next == 1/
+{
+ print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t))));
+ printf("\n");
+ next = 2;
+}
+
+pid\$target::ff_getsummons:entry
+/next == 2/
+{
+ print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t))));
+ printf("\n");
+ exit(0);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh
new file mode 100644
index 0000000..58811ff
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh
@@ -0,0 +1,83 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# Simple test that if we manually use the userland keyword that it
+# works.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+t="zelda_info_t"
+exe="tst.chasestrings.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -32 -qs /dev/stdin <<EOF
+typedef struct info {
+ char *zi_gamename;
+ int zi_ndungeons;
+ char *zi_villain;
+ int zi_haszelda;
+} info_t;
+
+pid$pid::has_princess:entry
+/next == 0/
+{
+ this->t = (userland info_t *)arg0;
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(this->t->zi_gamename), this->t->zi_ndungeons,
+ stringof(this->t->zi_villain), this->t->zi_haszelda);
+ next = 1;
+}
+
+pid$pid::has_dungeons:entry
+/next == 1/
+{
+ this->t = (userland info_t *)arg0;
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(this->t->zi_gamename), this->t->zi_ndungeons,
+ stringof(this->t->zi_villain), this->t->zi_haszelda);
+ next = 2;
+}
+
+pid$pid::has_villain:entry
+/next == 2/
+{
+ this->t = (userland info_t *)arg0;
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(this->t->zi_gamename), this->t->zi_ndungeons,
+ stringof(this->t->zi_villain), this->t->zi_haszelda);
+ exit(0);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out
new file mode 100644
index 0000000..219e406
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out
@@ -0,0 +1,4 @@
+game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1
+game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0
+game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1
+
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh
new file mode 100644
index 0000000..79d79de
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh
@@ -0,0 +1,72 @@
+#! /usr/bin/ksh
+#
+#
+# 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 (c) 2013 Joyent, Inc. All rights reserved.
+#
+
+#
+# This test is checking that we can read members and that pointers inside
+# members point to valid data that is intelligible, eg. strings.
+#
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+exe="tst.chasestrings.exe"
+
+elfdump "./$exe" | grep -q '.SUNW_ctf'
+if [[ $? -ne 0 ]]; then
+ echo "CTF does not exist in $exe, that's a bug" >&2
+ exit 1
+fi
+
+./$exe &
+pid=$!
+
+$dtrace -qs /dev/stdin <<EOF
+pid$pid::has_princess:entry
+/next == 0/
+{
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(args[0]->zi_gamename), args[0]->zi_ndungeons,
+ stringof(args[0]->zi_villain), args[0]->zi_haszelda);
+ next = 1;
+}
+
+pid$pid::has_dungeons:entry
+/next == 1/
+{
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(args[0]->zi_gamename), args[0]->zi_ndungeons,
+ stringof(args[0]->zi_villain), args[0]->zi_haszelda);
+ next = 2;
+}
+
+pid$pid::has_villain:entry
+/next == 2/
+{
+ printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n",
+ stringof(args[0]->zi_gamename), args[0]->zi_ndungeons,
+ stringof(args[0]->zi_villain), args[0]->zi_haszelda);
+ exit(0);
+}
+EOF
+rc=$?
+
+kill -9 $pid
+
+exit $rc
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out
new file mode 100644
index 0000000..219e406
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out
@@ -0,0 +1,4 @@
+game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1
+game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0
+game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1
+
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_open.c b/cddl/contrib/opensolaris/common/ctf/ctf_open.c
index 2148389..001cf5c 100644
--- a/cddl/contrib/opensolaris/common/ctf/ctf_open.c
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_open.c
@@ -25,7 +25,7 @@
* Use is subject to license terms.
*/
/*
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#include <ctf_impl.h>
@@ -788,6 +788,92 @@ bad:
}
/*
+ * Dupliate a ctf_file_t and its underlying section information into a new
+ * container. This works by copying the three ctf_sect_t's of the original
+ * container if they exist and passing those into ctf_bufopen. To copy those, we
+ * mmap anonymous memory with ctf_data_alloc and bcopy the data across. It's not
+ * the cheapest thing, but it's what we've got.
+ */
+ctf_file_t *
+ctf_dup(ctf_file_t *ofp)
+{
+ ctf_file_t *fp;
+ ctf_sect_t ctfsect, symsect, strsect;
+ ctf_sect_t *ctp, *symp, *strp;
+ void *cbuf, *symbuf, *strbuf;
+ int err;
+
+ cbuf = symbuf = strbuf = NULL;
+ /*
+ * The ctfsect isn't allowed to not exist, but the symbol and string
+ * section might not. We only need to copy the data of the section, not
+ * the name, as ctf_bufopen will take care of that.
+ */
+ bcopy(&ofp->ctf_data, &ctfsect, sizeof (ctf_sect_t));
+ cbuf = ctf_data_alloc(ctfsect.cts_size);
+ if (cbuf == NULL) {
+ (void) ctf_set_errno(ofp, ECTF_MMAP);
+ return (NULL);
+ }
+
+ bcopy(ctfsect.cts_data, cbuf, ctfsect.cts_size);
+ ctf_data_protect(cbuf, ctfsect.cts_size);
+ ctfsect.cts_data = cbuf;
+ ctfsect.cts_offset = 0;
+ ctp = &ctfsect;
+
+ if (ofp->ctf_symtab.cts_data != NULL) {
+ bcopy(&ofp->ctf_symtab, &symsect, sizeof (ctf_sect_t));
+ symbuf = ctf_data_alloc(symsect.cts_size);
+ if (symbuf == NULL) {
+ (void) ctf_set_errno(ofp, ECTF_MMAP);
+ goto err;
+ }
+ bcopy(symsect.cts_data, symbuf, symsect.cts_size);
+ ctf_data_protect(symbuf, symsect.cts_size);
+ symsect.cts_data = symbuf;
+ symsect.cts_offset = 0;
+ symp = &symsect;
+ } else {
+ symp = NULL;
+ }
+
+ if (ofp->ctf_strtab.cts_data != NULL) {
+ bcopy(&ofp->ctf_strtab, &strsect, sizeof (ctf_sect_t));
+ strbuf = ctf_data_alloc(strsect.cts_size);
+ if (strbuf == NULL) {
+ (void) ctf_set_errno(ofp, ECTF_MMAP);
+ goto err;
+ }
+ bcopy(strsect.cts_data, strbuf, strsect.cts_size);
+ ctf_data_protect(strbuf, strsect.cts_size);
+ strsect.cts_data = strbuf;
+ strsect.cts_offset = 0;
+ strp = &strsect;
+ } else {
+ strp = NULL;
+ }
+
+ fp = ctf_bufopen(ctp, symp, strp, &err);
+ if (fp == NULL) {
+ (void) ctf_set_errno(ofp, err);
+ goto err;
+ }
+
+ fp->ctf_flags |= LCTF_MMAP;
+
+ return (fp);
+
+err:
+ ctf_data_free(cbuf, ctfsect.cts_size);
+ if (symbuf != NULL)
+ ctf_data_free(symbuf, symsect.cts_size);
+ if (strbuf != NULL)
+ ctf_data_free(strbuf, strsect.cts_size);
+ 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
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_types.c b/cddl/contrib/opensolaris/common/ctf/ctf_types.c
index 290c518..ab1b9ff 100644
--- a/cddl/contrib/opensolaris/common/ctf/ctf_types.c
+++ b/cddl/contrib/opensolaris/common/ctf/ctf_types.c
@@ -25,8 +25,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <ctf_impl.h>
ssize_t
@@ -199,8 +197,9 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_t type)
* 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)
+static ssize_t
+ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
+ const char *qname)
{
ctf_decl_t cd;
ctf_decl_node_t *cdp;
@@ -255,6 +254,8 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
case CTF_K_INTEGER:
case CTF_K_FLOAT:
case CTF_K_TYPEDEF:
+ if (qname != NULL)
+ ctf_decl_sprintf(&cd, "%s`", qname);
ctf_decl_sprintf(&cd, "%s", name);
break;
case CTF_K_POINTER:
@@ -268,13 +269,22 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
break;
case CTF_K_STRUCT:
case CTF_K_FORWARD:
- ctf_decl_sprintf(&cd, "struct %s", name);
+ ctf_decl_sprintf(&cd, "struct ");
+ if (qname != NULL)
+ ctf_decl_sprintf(&cd, "%s`", qname);
+ ctf_decl_sprintf(&cd, "%s", name);
break;
case CTF_K_UNION:
- ctf_decl_sprintf(&cd, "union %s", name);
+ ctf_decl_sprintf(&cd, "union ");
+ if (qname != NULL)
+ ctf_decl_sprintf(&cd, "%s`", qname);
+ ctf_decl_sprintf(&cd, "%s", name);
break;
case CTF_K_ENUM:
- ctf_decl_sprintf(&cd, "enum %s", name);
+ ctf_decl_sprintf(&cd, "enum ");
+ if (qname != NULL)
+ ctf_decl_sprintf(&cd, "%s`", qname);
+ ctf_decl_sprintf(&cd, "%s", name);
break;
case CTF_K_VOLATILE:
ctf_decl_sprintf(&cd, "volatile");
@@ -301,6 +311,12 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
return (cd.cd_len);
}
+ssize_t
+ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
+{
+ return (ctf_type_qlname(fp, type, buf, len, NULL));
+}
+
/*
* 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.
@@ -308,10 +324,19 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
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);
+ ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL);
+ return (rv >= 0 && rv < len ? buf : NULL);
+}
+
+char *
+ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
+ const char *qname)
+{
+ ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname);
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.
diff --git a/cddl/contrib/opensolaris/common/util/strtolctype.h b/cddl/contrib/opensolaris/common/util/strtolctype.h
new file mode 100644
index 0000000..a1d1836
--- /dev/null
+++ b/cddl/contrib/opensolaris/common/util/strtolctype.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 (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL 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) 1988 AT&T */
+/* All Rights Reserved */
+
+#ifndef _COMMON_UTIL_CTYPE_H
+#define _COMMON_UTIL_CTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This header file contains a collection of macros that the strtou?ll?
+ * functions in common/util use to test characters. What we need is a kernel
+ * version of ctype.h.
+ *
+ * NOTE: These macros are used within several DTrace probe context functions.
+ * They must not be altered to make function calls or perform actions not
+ * safe in probe context.
+ */
+
+#if defined(sun) && (defined(_KERNEL) || defined(_BOOT))
+
+#define isalnum(ch) (isalpha(ch) || isdigit(ch))
+#define isalpha(ch) (isupper(ch) || islower(ch))
+#define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
+#define islower(ch) ((ch) >= 'a' && (ch) <= 'z')
+#define isspace(ch) (((ch) == ' ') || ((ch) == '\r') || ((ch) == '\n') || \
+ ((ch) == '\t') || ((ch) == '\f'))
+#define isupper(ch) ((ch) >= 'A' && (ch) <= 'Z')
+#define isxdigit(ch) (isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \
+ ((ch) >= 'A' && (ch) <= 'F'))
+
+#endif /* _KERNEL || _BOOT */
+
+#define DIGIT(x) \
+ (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
+
+#define MBASE ('z' - 'a' + 1 + 10)
+
+/*
+ * The following macro is a version of isalnum() that limits alphabetic
+ * characters to the ranges a-z and A-Z; locale dependent characters will not
+ * return 1. The members of a-z and A-Z are assumed to be in ascending order
+ * and contiguous.
+ */
+#define lisalnum(x) \
+ (isdigit(x) || ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMMON_UTIL_CTYPE_H */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
index b0f2b4a..6b571fa 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
@@ -25,7 +25,7 @@
*/
/*
- * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
@@ -1301,6 +1301,231 @@ dtrace_aggregate_walk(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg)
}
static int
+dt_aggregate_total(dtrace_hdl_t *dtp, boolean_t clear)
+{
+ dt_ahashent_t *h;
+ dtrace_aggdata_t **total;
+ dtrace_aggid_t max = DTRACE_AGGVARIDNONE, id;
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dt_ahash_t *hash = &agp->dtat_hash;
+ uint32_t tflags;
+
+ tflags = DTRACE_A_TOTAL | DTRACE_A_HASNEGATIVES | DTRACE_A_HASPOSITIVES;
+
+ /*
+ * If we need to deliver per-aggregation totals, we're going to take
+ * three passes over the aggregate: one to clear everything out and
+ * determine our maximum aggregation ID, one to actually total
+ * everything up, and a final pass to assign the totals to the
+ * individual elements.
+ */
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggdata_t *aggdata = &h->dtahe_data;
+
+ if ((id = dt_aggregate_aggvarid(h)) > max)
+ max = id;
+
+ aggdata->dtada_total = 0;
+ aggdata->dtada_flags &= ~tflags;
+ }
+
+ if (clear || max == DTRACE_AGGVARIDNONE)
+ return (0);
+
+ total = dt_zalloc(dtp, (max + 1) * sizeof (dtrace_aggdata_t *));
+
+ if (total == NULL)
+ return (-1);
+
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggdata_t *aggdata = &h->dtahe_data;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ dtrace_recdesc_t *rec;
+ caddr_t data;
+ int64_t val, *addr;
+
+ rec = &agg->dtagd_rec[agg->dtagd_nrecs - 1];
+ data = aggdata->dtada_data;
+ addr = (int64_t *)(uintptr_t)(data + rec->dtrd_offset);
+
+ switch (rec->dtrd_action) {
+ case DTRACEAGG_STDDEV:
+ val = dt_stddev((uint64_t *)addr, 1);
+ break;
+
+ case DTRACEAGG_SUM:
+ case DTRACEAGG_COUNT:
+ val = *addr;
+ break;
+
+ case DTRACEAGG_AVG:
+ val = addr[0] ? (addr[1] / addr[0]) : 0;
+ break;
+
+ default:
+ continue;
+ }
+
+ if (total[agg->dtagd_varid] == NULL) {
+ total[agg->dtagd_varid] = aggdata;
+ aggdata->dtada_flags |= DTRACE_A_TOTAL;
+ } else {
+ aggdata = total[agg->dtagd_varid];
+ }
+
+ if (val > 0)
+ aggdata->dtada_flags |= DTRACE_A_HASPOSITIVES;
+
+ if (val < 0) {
+ aggdata->dtada_flags |= DTRACE_A_HASNEGATIVES;
+ val = -val;
+ }
+
+ if (dtp->dt_options[DTRACEOPT_AGGZOOM] != DTRACEOPT_UNSET) {
+ val = (int64_t)((long double)val *
+ (1 / DTRACE_AGGZOOM_MAX));
+
+ if (val > aggdata->dtada_total)
+ aggdata->dtada_total = val;
+ } else {
+ aggdata->dtada_total += val;
+ }
+ }
+
+ /*
+ * And now one final pass to set everyone's total.
+ */
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggdata_t *aggdata = &h->dtahe_data, *t;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+
+ if ((t = total[agg->dtagd_varid]) == NULL || aggdata == t)
+ continue;
+
+ aggdata->dtada_total = t->dtada_total;
+ aggdata->dtada_flags |= (t->dtada_flags & tflags);
+ }
+
+ dt_free(dtp, total);
+
+ return (0);
+}
+
+static int
+dt_aggregate_minmaxbin(dtrace_hdl_t *dtp, boolean_t clear)
+{
+ dt_ahashent_t *h;
+ dtrace_aggdata_t **minmax;
+ dtrace_aggid_t max = DTRACE_AGGVARIDNONE, id;
+ dt_aggregate_t *agp = &dtp->dt_aggregate;
+ dt_ahash_t *hash = &agp->dtat_hash;
+
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggdata_t *aggdata = &h->dtahe_data;
+
+ if ((id = dt_aggregate_aggvarid(h)) > max)
+ max = id;
+
+ aggdata->dtada_minbin = 0;
+ aggdata->dtada_maxbin = 0;
+ aggdata->dtada_flags &= ~DTRACE_A_MINMAXBIN;
+ }
+
+ if (clear || max == DTRACE_AGGVARIDNONE)
+ return (0);
+
+ minmax = dt_zalloc(dtp, (max + 1) * sizeof (dtrace_aggdata_t *));
+
+ if (minmax == NULL)
+ return (-1);
+
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggdata_t *aggdata = &h->dtahe_data;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+ dtrace_recdesc_t *rec;
+ caddr_t data;
+ int64_t *addr;
+ int minbin = -1, maxbin = -1, i;
+ int start = 0, size;
+
+ rec = &agg->dtagd_rec[agg->dtagd_nrecs - 1];
+ size = rec->dtrd_size / sizeof (int64_t);
+ data = aggdata->dtada_data;
+ addr = (int64_t *)(uintptr_t)(data + rec->dtrd_offset);
+
+ switch (rec->dtrd_action) {
+ case DTRACEAGG_LQUANTIZE:
+ /*
+ * For lquantize(), we always display the entire range
+ * of the aggregation when aggpack is set.
+ */
+ start = 1;
+ minbin = start;
+ maxbin = size - 1 - start;
+ break;
+
+ case DTRACEAGG_QUANTIZE:
+ for (i = start; i < size; i++) {
+ if (!addr[i])
+ continue;
+
+ if (minbin == -1)
+ minbin = i - start;
+
+ maxbin = i - start;
+ }
+
+ if (minbin == -1) {
+ /*
+ * If we have no data (e.g., due to a clear()
+ * or negative increments), we'll use the
+ * zero bucket as both our min and max.
+ */
+ minbin = maxbin = DTRACE_QUANTIZE_ZEROBUCKET;
+ }
+
+ break;
+
+ default:
+ continue;
+ }
+
+ if (minmax[agg->dtagd_varid] == NULL) {
+ minmax[agg->dtagd_varid] = aggdata;
+ aggdata->dtada_flags |= DTRACE_A_MINMAXBIN;
+ aggdata->dtada_minbin = minbin;
+ aggdata->dtada_maxbin = maxbin;
+ continue;
+ }
+
+ if (minbin < minmax[agg->dtagd_varid]->dtada_minbin)
+ minmax[agg->dtagd_varid]->dtada_minbin = minbin;
+
+ if (maxbin > minmax[agg->dtagd_varid]->dtada_maxbin)
+ minmax[agg->dtagd_varid]->dtada_maxbin = maxbin;
+ }
+
+ /*
+ * And now one final pass to set everyone's minbin and maxbin.
+ */
+ for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) {
+ dtrace_aggdata_t *aggdata = &h->dtahe_data, *mm;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+
+ if ((mm = minmax[agg->dtagd_varid]) == NULL || aggdata == mm)
+ continue;
+
+ aggdata->dtada_minbin = mm->dtada_minbin;
+ aggdata->dtada_maxbin = mm->dtada_maxbin;
+ aggdata->dtada_flags |= DTRACE_A_MINMAXBIN;
+ }
+
+ dt_free(dtp, minmax);
+
+ return (0);
+}
+
+static int
dt_aggregate_walk_sorted(dtrace_hdl_t *dtp,
dtrace_aggregate_f *func, void *arg,
int (*sfunc)(const void *, const void *))
@@ -1309,6 +1534,23 @@ dt_aggregate_walk_sorted(dtrace_hdl_t *dtp,
dt_ahashent_t *h, **sorted;
dt_ahash_t *hash = &agp->dtat_hash;
size_t i, nentries = 0;
+ int rval = -1;
+
+ agp->dtat_flags &= ~(DTRACE_A_TOTAL | DTRACE_A_MINMAXBIN);
+
+ if (dtp->dt_options[DTRACEOPT_AGGHIST] != DTRACEOPT_UNSET) {
+ agp->dtat_flags |= DTRACE_A_TOTAL;
+
+ if (dt_aggregate_total(dtp, B_FALSE) != 0)
+ return (-1);
+ }
+
+ if (dtp->dt_options[DTRACEOPT_AGGPACK] != DTRACEOPT_UNSET) {
+ agp->dtat_flags |= DTRACE_A_MINMAXBIN;
+
+ if (dt_aggregate_minmaxbin(dtp, B_FALSE) != 0)
+ return (-1);
+ }
for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall)
nentries++;
@@ -1316,7 +1558,7 @@ dt_aggregate_walk_sorted(dtrace_hdl_t *dtp,
sorted = dt_alloc(dtp, nentries * sizeof (dt_ahashent_t *));
if (sorted == NULL)
- return (-1);
+ goto out;
for (h = hash->dtah_all, i = 0; h != NULL; h = h->dtahe_nextall)
sorted[i++] = h;
@@ -1340,14 +1582,20 @@ dt_aggregate_walk_sorted(dtrace_hdl_t *dtp,
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);
- }
+ if (dt_aggwalk_rval(dtp, h, func(&h->dtahe_data, arg)) == -1)
+ goto out;
}
+ rval = 0;
+out:
+ if (agp->dtat_flags & DTRACE_A_TOTAL)
+ (void) dt_aggregate_total(dtp, B_TRUE);
+
+ if (agp->dtat_flags & DTRACE_A_MINMAXBIN)
+ (void) dt_aggregate_minmaxbin(dtp, B_TRUE);
+
dt_free(dtp, sorted);
- return (0);
+ return (rval);
}
int
@@ -1870,6 +2118,8 @@ dtrace_aggregate_print(dtrace_hdl_t *dtp, FILE *fp,
{
dt_print_aggdata_t pd;
+ bzero(&pd, sizeof (pd));
+
pd.dtpa_dtp = dtp;
pd.dtpa_fp = fp;
pd.dtpa_allunprint = 1;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c
index 457b8fd..f937261 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c
@@ -23,8 +23,10 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ */
#include <sys/types.h>
#include <strings.h>
@@ -125,7 +127,7 @@ dt_copyvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
dvp->dtdv_flags |= DIFV_F_MOD;
bzero(&dn, sizeof (dn));
- dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type);
+ dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type, B_FALSE);
dt_node_diftype(pcb->pcb_hdl, &dn, &dvp->dtdv_type);
idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
index 64b98c4..a19152e 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
@@ -663,6 +663,8 @@ dt_action_printflike(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp,
static void
dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
{
+ int ctflib;
+
dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
boolean_t istrace = (dnp->dn_ident->di_id == DT_ACT_TRACE);
const char *act = istrace ? "trace" : "print";
@@ -694,7 +696,10 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
* 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.
+ * get the type information when we process the data after the fact. In
+ * the case where we are referring to userland CTF data, we also need to
+ * to identify which ctf container in question we care about and encode
+ * that within the name.
*/
if (dnp->dn_ident->di_id == DT_ACT_PRINT) {
dt_node_t *dret;
@@ -705,11 +710,27 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp);
n = snprintf(NULL, 0, "%s`%ld", dmp->dm_name, dret->dn_type) + 1;
+ if (dmp->dm_pid != 0) {
+ ctflib = dt_module_getlibid(dtp, dmp, dret->dn_ctfp);
+ assert(ctflib >= 0);
+ n = snprintf(NULL, 0, "%s`%d`%ld", dmp->dm_name,
+ ctflib, dret->dn_type) + 1;
+ } else {
+ n = snprintf(NULL, 0, "%s`%ld", dmp->dm_name,
+ dret->dn_type) + 1;
+ }
sdp->dtsd_strdata = dt_alloc(dtp, n);
if (sdp->dtsd_strdata == NULL)
longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
(void) snprintf(sdp->dtsd_strdata, n, "%s`%ld", dmp->dm_name,
dret->dn_type);
+ if (dmp->dm_pid != 0) {
+ (void) snprintf(sdp->dtsd_strdata, n, "%s`%d`%ld",
+ dmp->dm_name, ctflib, dret->dn_type);
+ } else {
+ (void) snprintf(sdp->dtsd_strdata, n, "%s`%ld",
+ dmp->dm_name, dret->dn_type);
+ }
}
ap->dtad_difo = dt_as(yypcb);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
index 8d9e494..ae1ed00 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
@@ -24,7 +24,7 @@
*/
/*
- * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
@@ -59,6 +59,25 @@ dt_fabsl(long double x)
return (x);
}
+static int
+dt_ndigits(long long val)
+{
+ int rval = 1;
+ long long cmp = 10;
+
+ if (val < 0) {
+ val = val == INT64_MIN ? INT64_MAX : -val;
+ rval++;
+ }
+
+ while (val > cmp && cmp > 0) {
+ rval++;
+ cmp *= 10;
+ }
+
+ return (rval < 4 ? 4 : rval);
+}
+
/*
* 128-bit arithmetic functions needed to support the stddev() aggregating
* action.
@@ -487,7 +506,125 @@ dt_nullrec()
return (DTRACE_CONSUME_NEXT);
}
-int
+static void
+dt_quantize_total(dtrace_hdl_t *dtp, int64_t datum, long double *total)
+{
+ long double val = dt_fabsl((long double)datum);
+
+ if (dtp->dt_options[DTRACEOPT_AGGZOOM] == DTRACEOPT_UNSET) {
+ *total += val;
+ return;
+ }
+
+ /*
+ * If we're zooming in on an aggregation, we want the height of the
+ * highest value to be approximately 95% of total bar height -- so we
+ * adjust up by the reciprocal of DTRACE_AGGZOOM_MAX when comparing to
+ * our highest value.
+ */
+ val *= 1 / DTRACE_AGGZOOM_MAX;
+
+ if (*total < val)
+ *total = val;
+}
+
+static int
+dt_print_quanthdr(dtrace_hdl_t *dtp, FILE *fp, int width)
+{
+ return (dt_printf(dtp, fp, "\n%*s %41s %-9s\n",
+ width ? width : 16, width ? "key" : "value",
+ "------------- Distribution -------------", "count"));
+}
+
+static int
+dt_print_quanthdr_packed(dtrace_hdl_t *dtp, FILE *fp, int width,
+ const dtrace_aggdata_t *aggdata, dtrace_actkind_t action)
+{
+ int min = aggdata->dtada_minbin, max = aggdata->dtada_maxbin;
+ int minwidth, maxwidth, i;
+
+ assert(action == DTRACEAGG_QUANTIZE || action == DTRACEAGG_LQUANTIZE);
+
+ if (action == DTRACEAGG_QUANTIZE) {
+ if (min != 0 && min != DTRACE_QUANTIZE_ZEROBUCKET)
+ min--;
+
+ if (max < DTRACE_QUANTIZE_NBUCKETS - 1)
+ max++;
+
+ minwidth = dt_ndigits(DTRACE_QUANTIZE_BUCKETVAL(min));
+ maxwidth = dt_ndigits(DTRACE_QUANTIZE_BUCKETVAL(max));
+ } else {
+ maxwidth = 8;
+ minwidth = maxwidth - 1;
+ max++;
+ }
+
+ if (dt_printf(dtp, fp, "\n%*s %*s .",
+ width, width > 0 ? "key" : "", minwidth, "min") < 0)
+ return (-1);
+
+ for (i = min; i <= max; i++) {
+ if (dt_printf(dtp, fp, "-") < 0)
+ return (-1);
+ }
+
+ return (dt_printf(dtp, fp, ". %*s | count\n", -maxwidth, "max"));
+}
+
+/*
+ * We use a subset of the Unicode Block Elements (U+2588 through U+258F,
+ * inclusive) to represent aggregations via UTF-8 -- which are expressed via
+ * 3-byte UTF-8 sequences.
+ */
+#define DTRACE_AGGUTF8_FULL 0x2588
+#define DTRACE_AGGUTF8_BASE 0x258f
+#define DTRACE_AGGUTF8_LEVELS 8
+
+#define DTRACE_AGGUTF8_BYTE0(val) (0xe0 | ((val) >> 12))
+#define DTRACE_AGGUTF8_BYTE1(val) (0x80 | (((val) >> 6) & 0x3f))
+#define DTRACE_AGGUTF8_BYTE2(val) (0x80 | ((val) & 0x3f))
+
+static int
+dt_print_quantline_utf8(dtrace_hdl_t *dtp, FILE *fp, int64_t val,
+ uint64_t normal, long double total)
+{
+ uint_t len = 40, i, whole, partial;
+ long double f = (dt_fabsl((long double)val) * len) / total;
+ const char *spaces = " ";
+
+ whole = (uint_t)f;
+ partial = (uint_t)((f - (long double)(uint_t)f) *
+ (long double)DTRACE_AGGUTF8_LEVELS);
+
+ if (dt_printf(dtp, fp, "|") < 0)
+ return (-1);
+
+ for (i = 0; i < whole; i++) {
+ if (dt_printf(dtp, fp, "%c%c%c",
+ DTRACE_AGGUTF8_BYTE0(DTRACE_AGGUTF8_FULL),
+ DTRACE_AGGUTF8_BYTE1(DTRACE_AGGUTF8_FULL),
+ DTRACE_AGGUTF8_BYTE2(DTRACE_AGGUTF8_FULL)) < 0)
+ return (-1);
+ }
+
+ if (partial != 0) {
+ partial = DTRACE_AGGUTF8_BASE - (partial - 1);
+
+ if (dt_printf(dtp, fp, "%c%c%c",
+ DTRACE_AGGUTF8_BYTE0(partial),
+ DTRACE_AGGUTF8_BYTE1(partial),
+ DTRACE_AGGUTF8_BYTE2(partial)) < 0)
+ return (-1);
+
+ i++;
+ }
+
+ return (dt_printf(dtp, fp, "%s %-9lld\n", spaces + i,
+ (long long)val / normal));
+}
+
+static int
dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val,
uint64_t normal, long double total, char positives, char negatives)
{
@@ -505,6 +642,11 @@ dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val,
if (!negatives) {
if (positives) {
+ if (dtp->dt_encoding == DT_ENCODING_UTF8) {
+ return (dt_print_quantline_utf8(dtp, fp, val,
+ normal, total));
+ }
+
f = (dt_fabsl((long double)val) * len) / total;
depth = (uint_t)(f + 0.5);
} else {
@@ -547,6 +689,73 @@ dt_print_quantline(dtrace_hdl_t *dtp, FILE *fp, int64_t val,
}
}
+/*
+ * As with UTF-8 printing of aggregations, we use a subset of the Unicode
+ * Block Elements (U+2581 through U+2588, inclusive) to represent our packed
+ * aggregation.
+ */
+#define DTRACE_AGGPACK_BASE 0x2581
+#define DTRACE_AGGPACK_LEVELS 8
+
+static int
+dt_print_packed(dtrace_hdl_t *dtp, FILE *fp,
+ long double datum, long double total)
+{
+ static boolean_t utf8_checked = B_FALSE;
+ static boolean_t utf8;
+ char *ascii = "__xxxxXX";
+ char *neg = "vvvvVV";
+ unsigned int len;
+ long double val;
+
+ if (!utf8_checked) {
+ char *term;
+
+ /*
+ * We want to determine if we can reasonably emit UTF-8 for our
+ * packed aggregation. To do this, we will check for terminals
+ * that are known to be primitive to emit UTF-8 on these.
+ */
+ utf8_checked = B_TRUE;
+
+ if (dtp->dt_encoding == DT_ENCODING_ASCII) {
+ utf8 = B_FALSE;
+ } else if (dtp->dt_encoding == DT_ENCODING_UTF8) {
+ utf8 = B_TRUE;
+ } else if ((term = getenv("TERM")) != NULL &&
+ (strcmp(term, "sun") == 0 ||
+ strcmp(term, "sun-color") == 0) ||
+ strcmp(term, "dumb") == 0) {
+ utf8 = B_FALSE;
+ } else {
+ utf8 = B_TRUE;
+ }
+ }
+
+ if (datum == 0)
+ return (dt_printf(dtp, fp, " "));
+
+ if (datum < 0) {
+ len = strlen(neg);
+ val = dt_fabsl(datum * (len - 1)) / total;
+ return (dt_printf(dtp, fp, "%c", neg[(uint_t)(val + 0.5)]));
+ }
+
+ if (utf8) {
+ int block = DTRACE_AGGPACK_BASE + (unsigned int)(((datum *
+ (DTRACE_AGGPACK_LEVELS - 1)) / total) + 0.5);
+
+ return (dt_printf(dtp, fp, "%c%c%c",
+ DTRACE_AGGUTF8_BYTE0(block),
+ DTRACE_AGGUTF8_BYTE1(block),
+ DTRACE_AGGUTF8_BYTE2(block)));
+ }
+
+ len = strlen(ascii);
+ val = (datum * (len - 1)) / total;
+ return (dt_printf(dtp, fp, "%c", ascii[(uint_t)(val + 0.5)]));
+}
+
int
dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
size_t size, uint64_t normal)
@@ -564,9 +773,9 @@ dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
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.
+ * There isn't any data. This is possible if the aggregation
+ * has been clear()'d or if negative increment values have been
+ * used. Regardless, we'll print the buckets around 0.
*/
first_bin = DTRACE_QUANTIZE_ZEROBUCKET - 1;
last_bin = DTRACE_QUANTIZE_ZEROBUCKET + 1;
@@ -584,11 +793,10 @@ dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
for (i = first_bin; i <= last_bin; i++) {
positives |= (data[i] > 0);
negatives |= (data[i] < 0);
- total += dt_fabsl((long double)data[i]);
+ dt_quantize_total(dtp, data[i], &total);
}
- if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value",
- "------------- Distribution -------------", "count") < 0)
+ if (dt_print_quanthdr(dtp, fp, 0) < 0)
return (-1);
for (i = first_bin; i <= last_bin; i++) {
@@ -605,6 +813,48 @@ dt_print_quantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
}
int
+dt_print_quantize_packed(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
+ size_t size, const dtrace_aggdata_t *aggdata)
+{
+ const int64_t *data = addr;
+ long double total = 0, count = 0;
+ int min = aggdata->dtada_minbin, max = aggdata->dtada_maxbin, i;
+ int64_t minval, maxval;
+
+ if (size != DTRACE_QUANTIZE_NBUCKETS * sizeof (uint64_t))
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ if (min != 0 && min != DTRACE_QUANTIZE_ZEROBUCKET)
+ min--;
+
+ if (max < DTRACE_QUANTIZE_NBUCKETS - 1)
+ max++;
+
+ minval = DTRACE_QUANTIZE_BUCKETVAL(min);
+ maxval = DTRACE_QUANTIZE_BUCKETVAL(max);
+
+ if (dt_printf(dtp, fp, " %*lld :", dt_ndigits(minval),
+ (long long)minval) < 0)
+ return (-1);
+
+ for (i = min; i <= max; i++) {
+ dt_quantize_total(dtp, data[i], &total);
+ count += data[i];
+ }
+
+ for (i = min; i <= max; i++) {
+ if (dt_print_packed(dtp, fp, data[i], total) < 0)
+ return (-1);
+ }
+
+ if (dt_printf(dtp, fp, ": %*lld | %lld\n",
+ -dt_ndigits(maxval), (long long)maxval, (long long)count) < 0)
+ return (-1);
+
+ return (0);
+}
+
+int
dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
size_t size, uint64_t normal)
{
@@ -651,7 +901,7 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
for (i = first_bin; i <= last_bin; i++) {
positives |= (data[i] > 0);
negatives |= (data[i] < 0);
- total += dt_fabsl((long double)data[i]);
+ dt_quantize_total(dtp, data[i], &total);
}
if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value",
@@ -663,8 +913,7 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
int err;
if (i == 0) {
- (void) snprintf(c, sizeof (c), "< %d",
- base / (uint32_t)normal);
+ (void) snprintf(c, sizeof (c), "< %d", base);
err = dt_printf(dtp, fp, "%16s ", c);
} else if (i == levels + 1) {
(void) snprintf(c, sizeof (c), ">= %d",
@@ -683,6 +932,59 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
return (0);
}
+/*ARGSUSED*/
+int
+dt_print_lquantize_packed(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
+ size_t size, const dtrace_aggdata_t *aggdata)
+{
+ const int64_t *data = addr;
+ long double total = 0, count = 0;
+ int min, max, base, err;
+ uint64_t arg;
+ uint16_t step, levels;
+ char c[32];
+ unsigned int i;
+
+ 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);
+
+ if (size != sizeof (uint64_t) * (levels + 2))
+ return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+ min = 0;
+ max = levels + 1;
+
+ if (min == 0) {
+ (void) snprintf(c, sizeof (c), "< %d", base);
+ err = dt_printf(dtp, fp, "%8s :", c);
+ } else {
+ err = dt_printf(dtp, fp, "%8d :", base + (min - 1) * step);
+ }
+
+ if (err < 0)
+ return (-1);
+
+ for (i = min; i <= max; i++) {
+ dt_quantize_total(dtp, data[i], &total);
+ count += data[i];
+ }
+
+ for (i = min; i <= max; i++) {
+ if (dt_print_packed(dtp, fp, data[i], total) < 0)
+ return (-1);
+ }
+
+ (void) snprintf(c, sizeof (c), ">= %d", base + (levels * step));
+ return (dt_printf(dtp, fp, ": %-8s | %lld\n", c, (long long)count));
+}
+
int
dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
size_t size, uint64_t normal)
@@ -740,7 +1042,7 @@ dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
for (i = first_bin; i <= last_bin; i++) {
positives |= (data[i] > 0);
negatives |= (data[i] < 0);
- total += dt_fabsl((long double)data[i]);
+ dt_quantize_total(dtp, data[i], &total);
}
if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value",
@@ -823,7 +1125,7 @@ dt_print_stddev(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
}
/*ARGSUSED*/
-int
+static int
dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
size_t nbytes, int width, int quiet, int forceraw)
{
@@ -876,10 +1178,12 @@ dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
if (j != nbytes)
break;
- if (quiet)
+ if (quiet) {
return (dt_printf(dtp, fp, "%s", c));
- else
- return (dt_printf(dtp, fp, " %-*s", width, c));
+ } else {
+ return (dt_printf(dtp, fp, " %s%*s",
+ width < 0 ? " " : "", width, c));
+ }
}
break;
@@ -1793,10 +2097,83 @@ dt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec)
static int
dt_print_datum(dtrace_hdl_t *dtp, FILE *fp, dtrace_recdesc_t *rec,
- caddr_t addr, size_t size, uint64_t normal)
+ caddr_t addr, size_t size, const dtrace_aggdata_t *aggdata,
+ uint64_t normal, dt_print_aggdata_t *pd)
{
- int err;
+ int err, width;
dtrace_actkind_t act = rec->dtrd_action;
+ boolean_t packed = pd->dtpa_agghist || pd->dtpa_aggpack;
+ dtrace_aggdesc_t *agg = aggdata->dtada_desc;
+
+ static struct {
+ size_t size;
+ int width;
+ int packedwidth;
+ } *fmt, fmttab[] = {
+ { sizeof (uint8_t), 3, 3 },
+ { sizeof (uint16_t), 5, 5 },
+ { sizeof (uint32_t), 8, 8 },
+ { sizeof (uint64_t), 16, 16 },
+ { 0, -50, 16 }
+ };
+
+ if (packed && pd->dtpa_agghisthdr != agg->dtagd_varid) {
+ dtrace_recdesc_t *r;
+
+ width = 0;
+
+ /*
+ * To print our quantization header for either an agghist or
+ * aggpack aggregation, we need to iterate through all of our
+ * of our records to determine their width.
+ */
+ for (r = rec; !DTRACEACT_ISAGG(r->dtrd_action); r++) {
+ for (fmt = fmttab; fmt->size &&
+ fmt->size != r->dtrd_size; fmt++)
+ continue;
+
+ width += fmt->packedwidth + 1;
+ }
+
+ if (pd->dtpa_agghist) {
+ if (dt_print_quanthdr(dtp, fp, width) < 0)
+ return (-1);
+ } else {
+ if (dt_print_quanthdr_packed(dtp, fp,
+ width, aggdata, r->dtrd_action) < 0)
+ return (-1);
+ }
+
+ pd->dtpa_agghisthdr = agg->dtagd_varid;
+ }
+
+ if (pd->dtpa_agghist && DTRACEACT_ISAGG(act)) {
+ char positives = aggdata->dtada_flags & DTRACE_A_HASPOSITIVES;
+ char negatives = aggdata->dtada_flags & DTRACE_A_HASNEGATIVES;
+ int64_t val;
+
+ assert(act == DTRACEAGG_SUM || act == DTRACEAGG_COUNT);
+ val = (long long)*((uint64_t *)addr);
+
+ if (dt_printf(dtp, fp, " ") < 0)
+ return (-1);
+
+ return (dt_print_quantline(dtp, fp, val, normal,
+ aggdata->dtada_total, positives, negatives));
+ }
+
+ if (pd->dtpa_aggpack && DTRACEACT_ISAGG(act)) {
+ switch (act) {
+ case DTRACEAGG_QUANTIZE:
+ return (dt_print_quantize_packed(dtp,
+ fp, addr, size, aggdata));
+ case DTRACEAGG_LQUANTIZE:
+ return (dt_print_lquantize_packed(dtp,
+ fp, addr, size, aggdata));
+ default:
+ break;
+ }
+ }
switch (act) {
case DTRACEACT_STACK:
@@ -1839,28 +2216,33 @@ dt_print_datum(dtrace_hdl_t *dtp, FILE *fp, dtrace_recdesc_t *rec,
break;
}
+ for (fmt = fmttab; fmt->size && fmt->size != size; fmt++)
+ continue;
+
+ width = packed ? fmt->packedwidth : fmt->width;
+
switch (size) {
case sizeof (uint64_t):
- err = dt_printf(dtp, fp, " %16lld",
+ err = dt_printf(dtp, fp, " %*lld", width,
/* LINTED - alignment */
(long long)*((uint64_t *)addr) / normal);
break;
case sizeof (uint32_t):
/* LINTED - alignment */
- err = dt_printf(dtp, fp, " %8d", *((uint32_t *)addr) /
+ err = dt_printf(dtp, fp, " %*d", width, *((uint32_t *)addr) /
(uint32_t)normal);
break;
case sizeof (uint16_t):
/* LINTED - alignment */
- err = dt_printf(dtp, fp, " %5d", *((uint16_t *)addr) /
+ err = dt_printf(dtp, fp, " %*d", width, *((uint16_t *)addr) /
(uint32_t)normal);
break;
case sizeof (uint8_t):
- err = dt_printf(dtp, fp, " %3d", *((uint8_t *)addr) /
+ err = dt_printf(dtp, fp, " %*d", width, *((uint8_t *)addr) /
(uint32_t)normal);
break;
default:
- err = dt_print_bytes(dtp, fp, addr, size, 50, 0, 0);
+ err = dt_print_bytes(dtp, fp, addr, size, width, 0, 0);
break;
}
@@ -1881,6 +2263,9 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
caddr_t addr;
size_t size;
+ pd->dtpa_agghist = (aggdata->dtada_flags & DTRACE_A_TOTAL);
+ pd->dtpa_aggpack = (aggdata->dtada_flags & DTRACE_A_MINMAXBIN);
+
/*
* Iterate over each record description in the key, printing the traced
* data, skipping the first datum (the tuple member created by the
@@ -1897,7 +2282,8 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
break;
}
- if (dt_print_datum(dtp, fp, rec, addr, size, 1) < 0)
+ if (dt_print_datum(dtp, fp, rec, addr,
+ size, aggdata, 1, pd) < 0)
return (-1);
if (dt_buffered_flush(dtp, NULL, rec, aggdata,
@@ -1920,7 +2306,8 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
assert(DTRACEACT_ISAGG(act));
normal = aggdata->dtada_normal;
- if (dt_print_datum(dtp, fp, rec, addr, size, normal) < 0)
+ if (dt_print_datum(dtp, fp, rec, addr,
+ size, aggdata, normal, pd) < 0)
return (-1);
if (dt_buffered_flush(dtp, NULL, rec, aggdata,
@@ -1931,8 +2318,10 @@ dt_print_aggs(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg)
agg->dtagd_flags |= DTRACE_AGD_PRINTED;
}
- if (dt_printf(dtp, fp, "\n") < 0)
- return (-1);
+ if (!pd->dtpa_agghist && !pd->dtpa_aggpack) {
+ if (dt_printf(dtp, fp, "\n") < 0)
+ return (-1);
+ }
if (dt_buffered_flush(dtp, NULL, NULL, aggdata,
DTRACE_BUFDATA_AGGFORMAT | DTRACE_BUFDATA_AGGLAST) < 0)
@@ -2401,7 +2790,7 @@ nofmt:
}
n = dt_print_bytes(dtp, fp, addr,
- tracememsize, 33, quiet, 1);
+ tracememsize, -33, quiet, 1);
tracememsize = 0;
@@ -2434,7 +2823,7 @@ nofmt:
break;
default:
n = dt_print_bytes(dtp, fp, addr,
- rec->dtrd_size, 33, quiet, 0);
+ rec->dtrd_size, -33, quiet, 0);
break;
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
index 871fdd5..d717d56 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
@@ -21,7 +21,8 @@
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -779,7 +780,7 @@ dt_decl_enumerator(char *s, dt_node_t *dnp)
yyintdecimal = 0;
dnp = dt_node_int(value);
- dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type);
+ dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type, B_FALSE);
if ((inp = malloc(sizeof (dt_idnode_t))) == NULL)
longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
@@ -821,6 +822,8 @@ dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip)
char *name;
int rv;
+ tip->dtt_flags = 0;
+
/*
* Based on our current #include depth and decl stack depth, determine
* which dynamic CTF module and scope to use when adding any new types.
@@ -828,6 +831,9 @@ dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip)
dmp = yypcb->pcb_idepth ? dtp->dt_cdefs : dtp->dt_ddefs;
flag = yypcb->pcb_dstack.ds_next ? CTF_ADD_NONROOT : CTF_ADD_ROOT;
+ if (ddp->dd_attr & DT_DA_USER)
+ tip->dtt_flags = DTT_FL_USER;
+
/*
* If we have already cached a CTF type for this decl, then we just
* return the type information for the cached type.
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h
index 2933155..d322875 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h
@@ -23,12 +23,14 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ */
#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>
@@ -59,6 +61,7 @@ typedef struct dt_decl {
#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 */
+#define DT_DA_USER 0x0200 /* user-land type specifier */
typedef enum dt_dclass {
DT_DC_DEFAULT, /* no storage class specified */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
index fff4235..c0af364 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
@@ -26,7 +26,8 @@
*/
/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
*/
#include <strings.h>
@@ -312,9 +313,10 @@ dt_dis_typestr(const dtrace_diftype_t *t, char *buf, size_t len)
(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);
+ if (t->dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF)) {
+ (void) snprintf(buf, len, "%s (%s) by %sref (size %lu)",
+ kind, ckind, (t->dtdt_flags & DIF_TF_BYUREF) ? "user " : "",
+ (ulong_t)t->dtdt_size);
} else {
(void) snprintf(buf, len, "%s (%s) (size %lu)",
kind, ckind, (ulong_t)t->dtdt_size);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
index d8dbbabb..2327ff7 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
@@ -111,7 +111,8 @@ static const struct {
{ EDT_BADAGGVAR, "Invalid aggregation variable identifier" },
{ EDT_OVERSION, "Client requested deprecated version of library" },
{ EDT_ENABLING_ERR, "Failed to enable probe" },
- { EDT_NOPROBES, "No probe sites found for declared provider" }
+ { EDT_NOPROBES, "No probe sites found for declared provider" },
+ { EDT_CANTLOAD, "Failed to load module" },
};
static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
index 0c12623..07790f4 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
@@ -23,8 +23,10 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include <dt_impl.h>
@@ -102,6 +104,7 @@
%token DT_KEY_TYPEDEF
%token DT_KEY_UNION
%token DT_KEY_UNSIGNED
+%token DT_KEY_USERLAND
%token DT_KEY_VOID
%token DT_KEY_VOLATILE
%token DT_KEY_WHILE
@@ -633,6 +636,7 @@ type_specifier: DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); }
| 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_USERLAND { $$ = dt_decl_attr(DT_DA_USER); }
| DT_KEY_STRING {
$$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string"));
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c
index 13adbb4..5a2f0e4 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c
@@ -22,6 +22,8 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -104,7 +106,7 @@ dt_idcook_sign(dt_node_t *dnp, dt_ident_t *idp,
}
}
- dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
}
/*
@@ -163,7 +165,7 @@ dt_idcook_assc(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
if (argc != 0)
isp->dis_args[argc - 1].dn_list = NULL;
- dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
} else {
dt_idcook_sign(dnp, idp, argc, args,
@@ -304,7 +306,7 @@ dt_idcook_func(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
}
dt_node_type_assign(&isp->dis_args[i],
- dtt.dtt_ctfp, dtt.dtt_type);
+ dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
}
}
@@ -391,7 +393,9 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
dt_node_type_assign(dnp,
prp->pr_argv[ap->dn_value].dtt_ctfp,
- prp->pr_argv[ap->dn_value].dtt_type);
+ prp->pr_argv[ap->dn_value].dtt_type,
+ prp->pr_argv[ap->dn_value].dtt_flags & DTT_FL_USER ?
+ B_TRUE : B_FALSE);
} else if ((dxp = dt_xlator_lookup(dtp,
nnp, xnp, DT_XLATE_FUZZY)) != NULL || (
@@ -419,7 +423,8 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
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));
+ dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp),
+ B_FALSE);
} else {
xyerror(D_ARGS_XLATOR, "translator for %s[%lld] from %s to %s "
@@ -465,7 +470,7 @@ dt_idcook_regs(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
idp->di_ctfp = dtt.dtt_ctfp;
idp->di_type = dtt.dtt_type;
- dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
}
/*ARGSUSED*/
@@ -487,7 +492,7 @@ dt_idcook_type(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
idp->di_type = dtt.dtt_type;
}
- dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
}
/*ARGSUSED*/
@@ -495,7 +500,7 @@ 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);
+ dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
}
static void
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
index 2bae220..b7abbc2 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
@@ -146,6 +146,10 @@ typedef struct dt_module {
caddr_t dm_reloc_offset; /* Symbol relocation offset. */
uintptr_t *dm_sec_offsets;
#endif
+ pid_t dm_pid; /* pid for this module */
+ uint_t dm_nctflibs; /* number of ctf children libraries */
+ ctf_file_t **dm_libctfp; /* process library ctf pointers */
+ char **dm_libctfn; /* names of process ctf containers */
} dt_module_t;
#define DT_DM_LOADED 0x1 /* module symbol and type data is loaded */
@@ -189,6 +193,9 @@ typedef struct dt_print_aggdata {
dtrace_aggvarid_t dtpa_id; /* aggregation variable of interest */
FILE *dtpa_fp; /* file pointer */
int dtpa_allunprint; /* print only unprinted aggregations */
+ int dtpa_agghist; /* print aggregation as histogram */
+ int dtpa_agghisthdr; /* aggregation histogram hdr printed */
+ int dtpa_aggpack; /* pack quantized aggregations */
} dt_print_aggdata_t;
typedef struct dt_dirpath {
@@ -283,6 +290,7 @@ struct dtrace_hdl {
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_encoding; /* dtrace output encoding (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 */
@@ -374,6 +382,14 @@ struct dtrace_hdl {
#define DT_STDC_XT 3 /* ISO C + K&R C compat with ISO: __STDC__=0 */
/*
+ * Values for the dt_encoding property, which is used to force a particular
+ * character encoding (overriding default behavior and/or automatic detection).
+ */
+#define DT_ENCODING_UNSET 0
+#define DT_ENCODING_ASCII 1
+#define DT_ENCODING_UTF8 2
+
+/*
* 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'.
@@ -536,7 +552,8 @@ enum {
EDT_BADAGGVAR, /* invalid aggregation variable identifier */
EDT_OVERSION, /* client is requesting deprecated version */
EDT_ENABLING_ERR, /* failed to enable probe */
- EDT_NOPROBES /* no probes sites for declared provider */
+ EDT_NOPROBES, /* no probes sites for declared provider */
+ EDT_CANTLOAD /* failed to load a module */
};
/*
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l
index b31933e..032d303 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l
@@ -23,6 +23,10 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*/
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include <string.h>
#include <stdlib.h>
@@ -93,13 +97,17 @@ static void unput(int);
%}
%e 1500 /* maximum nodes */
-%p 3700 /* maximum positions */
+%p 4900 /* maximum positions */
%n 600 /* maximum states */
+%a 3000 /* maximum transitions */
%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_ALTIDENT [a-zA-Z_][0-9a-zA-Z_]*
+RGX_LMID LM[0-9a-fA-F]+`
+RGX_MOD_IDENT [a-zA-Z_`][0-9a-z.A-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]?
@@ -169,6 +177,7 @@ if (yypcb->pcb_token != 0) {
<S0>typedef return (DT_KEY_TYPEDEF);
<S0>union return (DT_KEY_UNION);
<S0>unsigned return (DT_KEY_UNSIGNED);
+<S0>userland return (DT_KEY_USERLAND);
<S0>void return (DT_KEY_VOID);
<S0>volatile return (DT_KEY_VOLATILE);
<S0>while return (DT_KEY_WHILE);
@@ -347,7 +356,9 @@ if (yypcb->pcb_token != 0) {
return (DT_TOK_INT);
}
-<S0>{RGX_IDENT} {
+<S0>{RGX_IDENT} |
+<S0>{RGX_MOD_IDENT}{RGX_IDENT} |
+<S0>{RGX_MOD_IDENT} {
return (id_or_type(yytext));
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
index 497faa9..e3905c1 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
@@ -22,6 +22,9 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*/
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include <sys/types.h>
#if defined(sun)
@@ -50,6 +53,7 @@
#include <dirent.h>
#if !defined(sun)
#include <fcntl.h>
+#include <libproc_compat.h>
#endif
#include <dt_strtab.h>
@@ -462,6 +466,9 @@ static const dt_modops_t dt_modops_64 = {
dt_module_t *
dt_module_create(dtrace_hdl_t *dtp, const char *name)
{
+ long pid;
+ char *eptr;
+ dt_ident_t *idp;
uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
dt_module_t *dmp;
@@ -485,6 +492,32 @@ dt_module_create(dtrace_hdl_t *dtp, const char *name)
else
dmp->dm_ops = &dt_modops_32;
+ /*
+ * Modules for userland processes are special. They always refer to a
+ * specific process and have a copy of their CTF data from a specific
+ * instant in time. Any dt_module_t that begins with 'pid' is a module
+ * for a specific process, much like how any probe description that
+ * begins with 'pid' is special. pid123 refers to process 123. A module
+ * that is just 'pid' refers specifically to pid$target. This is
+ * generally done as D does not currently allow for macros to be
+ * evaluated when working with types.
+ */
+ if (strncmp(dmp->dm_name, "pid", 3) == 0) {
+ errno = 0;
+ if (dmp->dm_name[3] == '\0') {
+ idp = dt_idhash_lookup(dtp->dt_macros, "target");
+ if (idp != NULL && idp->di_id != 0)
+ dmp->dm_pid = idp->di_id;
+ } else {
+ pid = strtol(dmp->dm_name + 3, &eptr, 10);
+ if (errno == 0 && *eptr == '\0')
+ dmp->dm_pid = (pid_t)pid;
+ else
+ dt_dprintf("encountered malformed pid "
+ "module: %s\n", dmp->dm_name);
+ }
+ }
+
return (dmp);
}
@@ -554,12 +587,169 @@ dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp)
return (0);
}
+typedef struct dt_module_cb_arg {
+ struct ps_prochandle *dpa_proc;
+ dtrace_hdl_t *dpa_dtp;
+ dt_module_t *dpa_dmp;
+ uint_t dpa_count;
+} dt_module_cb_arg_t;
+
+/* ARGSUSED */
+static int
+dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj)
+{
+ ctf_file_t *fp;
+ dt_module_cb_arg_t *dcp = arg;
+
+ /* Try to grab a ctf container if it exists */
+ fp = Pname_to_ctf(dcp->dpa_proc, obj);
+ if (fp != NULL)
+ dcp->dpa_count++;
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj)
+{
+ ctf_file_t *fp;
+ char buf[MAXPATHLEN], *p;
+ dt_module_cb_arg_t *dcp = arg;
+ int count = dcp->dpa_count;
+ Lmid_t lmid;
+
+ fp = Pname_to_ctf(dcp->dpa_proc, obj);
+ if (fp == NULL)
+ return (0);
+ fp = ctf_dup(fp);
+ if (fp == NULL)
+ return (0);
+ dcp->dpa_dmp->dm_libctfp[count] = fp;
+ /*
+ * While it'd be nice to simply use objname here, because of our prior
+ * actions we'll always get a resolved object name to its on disk file.
+ * Like the pid provider, we need to tell a bit of a lie here. The type
+ * that the user thinks of is in terms of the libraries they requested,
+ * eg. libc.so.1, they don't care about the fact that it's
+ * libc_hwcap.so.1.
+ */
+ (void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf));
+ if ((p = strrchr(buf, '/')) == NULL)
+ p = buf;
+ else
+ p++;
+
+ /*
+ * If for some reason we can't find a link map id for this module, which
+ * would be really quite weird. We instead just say the link map id is
+ * zero.
+ */
+ if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0)
+ lmid = 0;
+
+ if (lmid == 0)
+ dcp->dpa_dmp->dm_libctfn[count] = strdup(p);
+ else
+ (void) asprintf(&dcp->dpa_dmp->dm_libctfn[count],
+ "LM%x`%s", lmid, p);
+ if (dcp->dpa_dmp->dm_libctfn[count] == NULL)
+ return (1);
+ ctf_setspecific(fp, dcp->dpa_dmp);
+ dcp->dpa_count++;
+ return (0);
+}
+
+/*
+ * We've been asked to load data that belongs to another process. As such we're
+ * going to pgrab it at this instant, load everything that we might ever care
+ * about, and then drive on. The reason for this is that the process that we're
+ * interested in might be changing. As long as we have grabbed it, then this
+ * can't be a problem for us.
+ *
+ * For now, we're actually going to punt on most things and just try to get CTF
+ * data, nothing else. Basically this is only useful as a source of type
+ * information, we can't go and do the stacktrace lookups, etc.
+ */
+static int
+dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+ struct ps_prochandle *p;
+ dt_module_cb_arg_t arg;
+
+ /*
+ * Note that on success we do not release this hold. We must hold this
+ * for our life time.
+ */
+ p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
+ if (p == NULL) {
+ dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid);
+ return (dt_set_errno(dtp, EDT_CANTLOAD));
+ }
+ dt_proc_lock(dtp, p);
+
+ arg.dpa_proc = p;
+ arg.dpa_dtp = dtp;
+ arg.dpa_dmp = dmp;
+ arg.dpa_count = 0;
+ if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) {
+ dt_dprintf("failed to iterate objects\n");
+ dt_proc_release(dtp, p);
+ return (dt_set_errno(dtp, EDT_CANTLOAD));
+ }
+
+ if (arg.dpa_count == 0) {
+ dt_dprintf("no ctf data present\n");
+ dt_proc_unlock(dtp, p);
+ dt_proc_release(dtp, p);
+ return (dt_set_errno(dtp, EDT_CANTLOAD));
+ }
+
+ dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count);
+ if (dmp->dm_libctfp == NULL) {
+ dt_proc_unlock(dtp, p);
+ dt_proc_release(dtp, p);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+ bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count);
+
+ dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count);
+ if (dmp->dm_libctfn == NULL) {
+ free(dmp->dm_libctfp);
+ dt_proc_unlock(dtp, p);
+ dt_proc_release(dtp, p);
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ }
+ bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count);
+
+ dmp->dm_nctflibs = arg.dpa_count;
+
+ arg.dpa_count = 0;
+ if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) {
+ dt_proc_unlock(dtp, p);
+ dt_module_unload(dtp, dmp);
+ dt_proc_release(dtp, p);
+ return (dt_set_errno(dtp, EDT_CANTLOAD));
+ }
+ assert(arg.dpa_count == dmp->dm_nctflibs);
+ dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count,
+ (int)dmp->dm_pid);
+
+ dt_proc_unlock(dtp, p);
+ dt_proc_release(dtp, p);
+ dmp->dm_flags |= DT_DM_LOADED;
+
+ 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 */
+ if (dmp->dm_pid != 0)
+ return (dt_module_load_proc(dtp, dmp));
+
dmp->dm_ctdata.cts_name = ".SUNW_ctf";
dmp->dm_ctdata.cts_type = SHT_PROGBITS;
dmp->dm_ctdata.cts_flags = 0;
@@ -645,6 +835,14 @@ dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp)
return (0);
}
+int
+dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+ if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0)
+ return (1);
+ return (dt_module_getctf(dtp, dmp) != NULL);
+}
+
ctf_file_t *
dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
{
@@ -718,6 +916,8 @@ err:
void
dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
{
+ int i;
+
ctf_close(dmp->dm_ctfp);
dmp->dm_ctfp = NULL;
@@ -733,6 +933,17 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
}
#endif
+ if (dmp->dm_libctfp != NULL) {
+ for (i = 0; i < dmp->dm_nctflibs; i++) {
+ ctf_close(dmp->dm_libctfp[i]);
+ free(dmp->dm_libctfn[i]);
+ }
+ free(dmp->dm_libctfp);
+ free(dmp->dm_libctfn);
+ dmp->dm_libctfp = NULL;
+ dmp->dm_nctflibs = 0;
+ }
+
bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));
bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));
bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));
@@ -778,6 +989,8 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
(void) elf_end(dmp->dm_elf);
dmp->dm_elf = NULL;
+ dmp->dm_pid = 0;
+
dmp->dm_flags &= ~DT_DM_LOADED;
}
@@ -866,6 +1079,34 @@ dt_module_modelname(dt_module_t *dmp)
return ("32-bit");
}
+/* ARGSUSED */
+int
+dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp)
+{
+ int i;
+
+ for (i = 0; i < dmp->dm_nctflibs; i++) {
+ if (dmp->dm_libctfp[i] == fp)
+ return (i);
+ }
+
+ return (-1);
+}
+
+/* ARGSUSED */
+ctf_file_t *
+dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
+{
+ int i;
+
+ for (i = 0; i < dmp->dm_nctflibs; i++) {
+ if (strcmp(dmp->dm_libctfn[i], name) == 0)
+ return (dmp->dm_libctfp[i]);
+ }
+
+ return (NULL);
+}
+
/*
* 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>/.
@@ -1294,8 +1535,10 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
dt_module_t *dmp;
int found = 0;
ctf_id_t id;
- uint_t n;
+ uint_t n, i;
int justone;
+ ctf_file_t *fp;
+ char *buf, *p, *q;
uint_t mask = 0; /* mask of dt_module flags to match */
uint_t bits = 0; /* flag bits that must be present */
@@ -1310,7 +1553,6 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
return (-1); /* dt_errno is set for us */
n = 1;
justone = 1;
-
} else {
if (object == DTRACE_OBJ_KMODS)
mask = bits = DT_DM_KERNEL;
@@ -1334,7 +1576,7 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
* 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 (dt_module_hasctf(dtp, dmp) == 0) {
if (justone)
return (-1);
continue;
@@ -1346,13 +1588,38 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
* '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) {
+ if (dmp->dm_pid == 0) {
+ id = ctf_lookup_by_name(dmp->dm_ctfp, name);
+ fp = dmp->dm_ctfp;
+ } else {
+ if ((p = strchr(name, '`')) != NULL) {
+ buf = strdup(name);
+ if (buf == NULL)
+ return (dt_set_errno(dtp, EDT_NOMEM));
+ p = strchr(buf, '`');
+ if ((q = strchr(p + 1, '`')) != NULL)
+ p = q;
+ *p = '\0';
+ fp = dt_module_getctflib(dtp, dmp, buf);
+ if (fp == NULL || (id = ctf_lookup_by_name(fp,
+ p + 1)) == CTF_ERR)
+ id = CTF_ERR;
+ free(buf);
+ } else {
+ for (i = 0; i < dmp->dm_nctflibs; i++) {
+ fp = dmp->dm_libctfp[i];
+ id = ctf_lookup_by_name(fp, name);
+ if (id != CTF_ERR)
+ break;
+ }
+ }
+ }
+ if (id != CTF_ERR) {
tip->dtt_object = dmp->dm_name;
- tip->dtt_ctfp = dmp->dm_ctfp;
+ tip->dtt_ctfp = fp;
tip->dtt_type = id;
-
- if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve(
- dmp->dm_ctfp, id)) != CTF_K_FORWARD)
+ if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
+ CTF_K_FORWARD)
return (0);
found++;
@@ -1374,6 +1641,7 @@ dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
tip->dtt_object = NULL;
tip->dtt_ctfp = NULL;
tip->dtt_type = CTF_ERR;
+ tip->dtt_flags = 0;
if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)
return (dt_set_errno(dtp, EDT_NOMOD));
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h
index 8334a2b..d103e02 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h
@@ -23,12 +23,13 @@
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#ifndef _DT_MODULE_H
#define _DT_MODULE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <dt_impl.h>
#ifdef __cplusplus
@@ -43,11 +44,16 @@ 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 int dt_module_hasctf(dtrace_hdl_t *, dt_module_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 *);
+extern int dt_module_getlibid(dtrace_hdl_t *, dt_module_t *,
+ const ctf_file_t *);
+extern ctf_file_t *dt_module_getctflib(dtrace_hdl_t *, dt_module_t *,
+ const char *);
#ifdef __cplusplus
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
index 9c9b2a6..cf6f2e9 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
@@ -122,8 +122,12 @@
#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_1_9_1 DT_VERSION_NUMBER(1, 9, 1)
-#define DT_VERS_LATEST DT_VERS_1_9_1
-#define DT_VERS_STRING "Sun D 1.9.1"
+#define DT_VERS_1_10 DT_VERSION_NUMBER(1, 10, 0)
+#define DT_VERS_1_11 DT_VERSION_NUMBER(1, 11, 0)
+#define DT_VERS_1_12 DT_VERSION_NUMBER(1, 12, 0)
+#define DT_VERS_1_12_1 DT_VERSION_NUMBER(1, 12, 1)
+#define DT_VERS_LATEST DT_VERS_1_12_1
+#define DT_VERS_STRING "Sun D 1.12.1"
const dt_version_t _dtrace_versions[] = {
DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@@ -145,6 +149,10 @@ const dt_version_t _dtrace_versions[] = {
DT_VERS_1_8_1, /* D API 1.8.1 */
DT_VERS_1_9, /* D API 1.9 */
DT_VERS_1_9_1, /* D API 1.9.1 */
+ DT_VERS_1_10, /* D API 1.10 */
+ DT_VERS_1_11, /* D API 1.11 */
+ DT_VERS_1_12, /* D API 1.12 */
+ DT_VERS_1_12_1, /* D API 1.12.1 */
0
};
@@ -275,6 +283,8 @@ static const dt_ident_t _dtrace_globals[] = {
&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)" },
+{ "getf", DT_IDENT_FUNC, 0, DIF_SUBR_GETF, DT_ATTR_STABCMN, DT_VERS_1_10,
+ &dt_idops_func, "file_t *(int)" },
{ "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,
@@ -297,6 +307,8 @@ static const dt_ident_t _dtrace_globals[] = {
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" },
+{ "json", DT_IDENT_FUNC, 0, DIF_SUBR_JSON, DT_ATTR_STABCMN, DT_VERS_1_11,
+ &dt_idops_func, "string(const char *, const char *)" },
{ "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,
@@ -444,6 +456,8 @@ static const dt_ident_t _dtrace_globals[] = {
&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 *)" },
+{ "strtoll", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOLL, DT_ATTR_STABCMN, DT_VERS_1_11,
+ &dt_idops_func, "int64_t(const char *, [int])" },
{ "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,
@@ -1148,6 +1162,7 @@ alloc:
dtp->dt_linktype = DT_LTYP_ELF;
dtp->dt_xlatemode = DT_XL_STATIC;
dtp->dt_stdcmode = DT_STDC_XA;
+ dtp->dt_encoding = DT_ENCODING_UNSET;
dtp->dt_version = version;
dtp->dt_fd = dtfd;
dtp->dt_ftfd = ftfd;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
index c20d250..832af88 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
@@ -25,6 +25,7 @@
*/
/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
@@ -338,6 +339,23 @@ dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
/*ARGSUSED*/
static int
+dt_opt_encoding(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ if (strcmp(arg, "ascii") == 0)
+ dtp->dt_encoding = DT_ENCODING_ASCII;
+ else if (strcmp(arg, "utf8") == 0)
+ dtp->dt_encoding = DT_ENCODING_UTF8;
+ 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)
@@ -928,6 +946,7 @@ static const dt_option_t _dtrace_ctoptions[] = {
{ "define", dt_opt_cpp_opts, (uintptr_t)"-D" },
{ "droptags", dt_opt_droptags },
{ "empty", dt_opt_cflags, DTRACE_C_EMPTY },
+ { "encoding", dt_opt_encoding },
{ "errtags", dt_opt_cflags, DTRACE_C_ETAGS },
{ "evaltime", dt_opt_evaltime },
{ "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },
@@ -988,11 +1007,14 @@ static const dt_option_t _dtrace_rtoptions[] = {
* Dynamic run-time options.
*/
static const dt_option_t _dtrace_drtoptions[] = {
+ { "agghist", dt_opt_runtime, DTRACEOPT_AGGHIST },
+ { "aggpack", dt_opt_runtime, DTRACEOPT_AGGPACK },
{ "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 },
+ { "aggzoom", dt_opt_runtime, DTRACEOPT_AGGZOOM },
{ "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },
{ "quiet", dt_opt_runtime, DTRACEOPT_QUIET },
{ "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
index 5b3be7d..6ce3dad 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
@@ -22,8 +22,8 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2011, Joyent Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -197,7 +197,7 @@ 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;
+ const char *p, *q, *r, *end, *obj;
for (p = s, end = s + strlen(s); *p != '\0'; p = q) {
while (isspace(*p))
@@ -225,8 +225,23 @@ dt_type_lookup(const char *s, dtrace_typeinfo_t *tip)
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));
+ /*
+ * There may be at most three delimeters. The second
+ * delimeter is usually used to distinguish the type
+ * within a given module, however, there could be a link
+ * map id on the scene in which case that delimeter
+ * would be the third. We determine presence of the lmid
+ * if it rouglhly meets the from LM[0-9]
+ */
+ if ((r = strchr(q + 1, '`')) != NULL &&
+ ((r = strchr(r + 1, '`')) != NULL)) {
+ if (strchr(r + 1, '`') != NULL)
+ return (dt_set_errno(dtp,
+ EDT_BADSCOPE));
+ if (q[1] != 'L' || q[2] != 'M')
+ return (dt_set_errno(dtp,
+ EDT_BADSCOPE));
+ }
return (dtrace_lookup_by_type(dtp, object, type, tip));
}
@@ -256,6 +271,7 @@ dt_type_pointer(dtrace_typeinfo_t *tip)
ctf_file_t *ctfp = tip->dtt_ctfp;
ctf_id_t type = tip->dtt_type;
ctf_id_t base = ctf_type_resolve(ctfp, type);
+ uint_t bflags = tip->dtt_flags;
dt_module_t *dmp;
ctf_id_t ptr;
@@ -287,6 +303,7 @@ dt_type_pointer(dtrace_typeinfo_t *tip)
tip->dtt_object = dmp->dm_name;
tip->dtt_ctfp = dmp->dm_ctfp;
tip->dtt_type = ptr;
+ tip->dtt_flags = bflags;
return (0);
}
@@ -390,7 +407,7 @@ 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_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type, B_FALSE);
dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
}
@@ -659,7 +676,8 @@ dt_node_attr_assign(dt_node_t *dnp, dtrace_attribute_t attr)
}
void
-dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type)
+dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type,
+ boolean_t user)
{
ctf_id_t base = ctf_type_resolve(fp, type);
uint_t kind = ctf_type_kind(fp, base);
@@ -691,6 +709,9 @@ dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type)
type == DT_DYN_TYPE(yypcb->pcb_hdl))
dnp->dn_flags |= DT_NF_REF;
+ if (user)
+ dnp->dn_flags |= DT_NF_USERLAND;
+
dnp->dn_flags |= DT_NF_COOKED;
dnp->dn_ctfp = fp;
dnp->dn_type = type;
@@ -728,6 +749,7 @@ size_t
dt_node_type_size(const dt_node_t *dnp)
{
ctf_id_t base;
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
if (dnp->dn_kind == DT_NODE_STRING)
return (strlen(dnp->dn_string) + 1);
@@ -740,6 +762,20 @@ dt_node_type_size(const dt_node_t *dnp)
if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_FORWARD)
return (0);
+ /*
+ * Here we have a 32-bit user pointer that is being used with a 64-bit
+ * kernel. When we're using it and its tagged as a userland reference --
+ * then we need to keep it as a 32-bit pointer. However, if we are
+ * referring to it as a kernel address, eg. being used after a copyin()
+ * then we need to make sure that we actually return the kernel's size
+ * of a pointer, 8 bytes.
+ */
+ if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_POINTER &&
+ ctf_getmodel(dnp->dn_ctfp) == CTF_MODEL_ILP32 &&
+ !(dnp->dn_flags & DT_NF_USERLAND) &&
+ dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
+ return (8);
+
return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type));
}
@@ -1226,7 +1262,7 @@ dt_node_int(uintmax_t value)
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);
+ dtp->dt_ints[i].did_type, B_FALSE);
/*
* If a prefix character is present in macro text, add
@@ -1261,7 +1297,7 @@ dt_node_string(char *string)
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));
+ dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp), B_FALSE);
return (dnp);
}
@@ -1337,7 +1373,8 @@ dt_node_type(dt_decl_t *ddp)
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);
+
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, dtt.dtt_flags);
if (dtt.dtt_ctfp == dtp->dt_cdefs->dm_ctfp ||
dtt.dtt_ctfp == dtp->dt_ddefs->dm_ctfp)
@@ -1581,7 +1618,8 @@ dt_node_decl(void)
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);
+ dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type,
+ B_FALSE);
else if (idp != NULL)
(void) dt_ident_cook(&idn, idp, NULL);
@@ -1791,7 +1829,7 @@ dt_node_offsetof(dt_decl_t *ddp, char *s)
}
bzero(&dn, sizeof (dn));
- dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type);
+ dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type, B_FALSE);
if (dn.dn_flags & DT_NF_BITFIELD) {
xyerror(D_OFFSETOF_BITFIELD,
@@ -1847,7 +1885,8 @@ dt_node_op1(int op, dt_node_t *cp)
}
dt_node_type_assign(cp, dtp->dt_ddefs->dm_ctfp,
- ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"));
+ ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"),
+ B_FALSE);
cp->dn_kind = DT_NODE_INT;
cp->dn_op = DT_TOK_INT;
@@ -1925,17 +1964,17 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
case DT_TOK_LOR:
dnp->dn_value = l || r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
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));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_LAND:
dnp->dn_value = l && r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_BOR:
dnp->dn_value = l | r;
@@ -1952,12 +1991,12 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
case DT_TOK_EQU:
dnp->dn_value = l == r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_NEQ:
dnp->dn_value = l != r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_LT:
dt_node_promote(lp, rp, dnp);
@@ -1966,7 +2005,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
else
dnp->dn_value = l < r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_LE:
dt_node_promote(lp, rp, dnp);
@@ -1975,7 +2014,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
else
dnp->dn_value = l <= r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_GT:
dt_node_promote(lp, rp, dnp);
@@ -1984,7 +2023,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
else
dnp->dn_value = l > r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_GE:
dt_node_promote(lp, rp, dnp);
@@ -1993,7 +2032,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp)
else
dnp->dn_value = l >= r;
dt_node_type_assign(dnp,
- DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
break;
case DT_TOK_LSH:
dnp->dn_value = l << r;
@@ -2234,7 +2273,7 @@ dt_node_inline(dt_node_t *expr)
* 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_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
dt_node_attr_assign(dnp, _dtrace_defattr);
if (dt_node_is_void(dnp)) {
@@ -2389,7 +2428,8 @@ dt_node_member(dt_decl_t *ddp, char *name, dt_node_t *expr)
dnp->dn_membexpr = expr;
if (ddp != NULL)
- dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type,
+ dtt.dtt_flags);
return (dnp);
}
@@ -2420,10 +2460,10 @@ dt_node_xlator(dt_decl_t *ddp, dt_decl_t *sdp, char *name, dt_node_t *members)
}
bzero(&sn, sizeof (sn));
- dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type);
+ dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type, B_FALSE);
bzero(&dn, sizeof (dn));
- dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type);
+ dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type, B_FALSE);
if (dt_xlator_lookup(dtp, &sn, &dn, DT_XLATE_EXACT) != NULL) {
xyerror(D_XLATE_REDECL,
@@ -2669,7 +2709,7 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
attr = dt_ident_cook(dnp, idp, NULL);
else {
dt_node_type_assign(dnp,
- DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE);
attr = idp->di_attr;
}
@@ -2745,7 +2785,8 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
dnp->dn_ident = idp;
dnp->dn_flags |= DT_NF_LVALUE;
- dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type,
+ dtt.dtt_flags);
dt_node_attr_assign(dnp, _dtrace_symattr);
if (uref) {
@@ -2793,7 +2834,7 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
attr = dt_ident_cook(dnp, idp, NULL);
else {
dt_node_type_assign(dnp,
- DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+ DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE);
attr = idp->di_attr;
}
@@ -2896,7 +2937,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
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);
+ dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type,
+ dtt.dtt_flags);
}
if (cp->dn_kind == DT_NODE_VAR)
@@ -2913,7 +2955,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
dnp->dn_ident = &dxp->dx_souid;
dt_node_type_assign(dnp,
- dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type);
+ dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type,
+ cp->dn_flags & DT_NF_USERLAND);
break;
}
@@ -2933,7 +2976,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
"cannot dereference non-pointer type\n");
}
- dt_node_type_assign(dnp, cp->dn_ctfp, type);
+ dt_node_type_assign(dnp, cp->dn_ctfp, type,
+ cp->dn_flags & DT_NF_USERLAND);
base = ctf_type_resolve(cp->dn_ctfp, type);
kind = ctf_type_kind(cp->dn_ctfp, base);
@@ -2990,7 +3034,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
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));
+ dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp),
+ B_FALSE);
break;
case DT_TOK_ADDROF:
@@ -3023,10 +3068,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
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;
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type,
+ cp->dn_flags & DT_NF_USERLAND);
break;
case DT_TOK_SIZEOF:
@@ -3041,7 +3084,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
}
dt_node_type_assign(dnp, dtp->dt_ddefs->dm_ctfp,
- ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"));
+ ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"),
+ B_FALSE);
break;
case DT_TOK_STRINGOF:
@@ -3051,7 +3095,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
"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));
+ dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp),
+ cp->dn_flags & DT_NF_USERLAND);
break;
case DT_TOK_PREINC:
@@ -3244,7 +3289,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
"of scalar type\n", opstr(op));
}
- dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp),
+ B_FALSE);
dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
break;
@@ -3288,7 +3334,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
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_type_assign(rp, lp->dn_ctfp, lp->dn_type,
+ B_FALSE);
dt_node_attr_assign(rp, _dtrace_symattr);
}
@@ -3320,7 +3367,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
dt_node_type_name(rp, n2, sizeof (n2)));
}
- dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+ dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp),
+ B_FALSE);
dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
break;
@@ -3368,7 +3416,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
dt_node_type_name(rp, n2, sizeof (n2)));
}
- dt_node_type_assign(dnp, ctfp, type);
+ dt_node_type_assign(dnp, ctfp, type, B_FALSE);
dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
if (uref)
@@ -3509,7 +3557,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
*/
if (lp->dn_kind == DT_NODE_VAR &&
dt_ident_unref(lp->dn_ident)) {
- dt_node_type_assign(lp, ctfp, type);
+ dt_node_type_assign(lp, ctfp, type, B_FALSE);
dt_ident_type_assign(lp->dn_ident, ctfp, type);
if (uref) {
@@ -3723,7 +3771,7 @@ asgn_common:
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_type_assign(dnp, ctfp, m.ctm_type, B_FALSE);
dt_node_attr_assign(dnp, lp->dn_attr);
if (op == DT_TOK_PTR && (kind != CTF_K_ARRAY ||
@@ -3849,7 +3897,8 @@ asgn_common:
}
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_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp),
+ B_FALSE);
dt_node_attr_assign(dnp,
dt_attr_min(rp->dn_attr, dnp->dn_ident->di_attr));
break;
@@ -4014,7 +4063,7 @@ dt_cook_op3(dt_node_t *dnp, uint_t idflags)
"used in a conditional context\n");
}
- dt_node_type_assign(dnp, ctfp, type);
+ dt_node_type_assign(dnp, ctfp, type, B_FALSE);
dt_node_attr_assign(dnp, dt_attr_min(dnp->dn_expr->dn_attr,
dt_attr_min(lp->dn_attr, rp->dn_attr)));
@@ -4047,7 +4096,8 @@ dt_cook_aggregation(dt_node_t *dnp, uint_t idflags)
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_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp),
+ B_FALSE);
dt_node_attr_assign(dnp, dnp->dn_ident->di_attr);
}
@@ -4249,7 +4299,8 @@ dt_cook_xlator(dt_node_t *dnp, uint_t idflags)
}
(void) dt_node_cook(mnp, DT_IDFLG_REF);
- dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type);
+ dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type,
+ B_FALSE);
attr = dt_attr_min(attr, mnp->dn_attr);
if (dt_node_is_argcompat(mnp, mnp->dn_membexpr) == 0) {
@@ -4268,7 +4319,7 @@ dt_cook_xlator(dt_node_t *dnp, uint_t idflags)
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_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE);
dt_node_attr_assign(dnp, _dtrace_defattr);
return (dnp);
@@ -4561,7 +4612,9 @@ dt_node_diftype(dtrace_hdl_t *dtp, const dt_node_t *dnp, dtrace_diftype_t *tp)
ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type));
}
- tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? DIF_TF_BYREF : 0;
+ tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ?
+ (dnp->dn_flags & DT_NF_USERLAND) ? DIF_TF_BYUREF :
+ DIF_TF_BYREF : 0;
tp->dtdt_pad = 0;
tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
index 6064efb..38f21c9 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
@@ -22,12 +22,14 @@
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ */
#ifndef _DT_PARSER_H
#define _DT_PARSER_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/dtrace.h>
@@ -223,7 +225,7 @@ 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_assign(dt_node_t *, ctf_file_t *, ctf_id_t, boolean_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 *);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
index b145818..c865a2d 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
@@ -23,6 +23,9 @@
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include <assert.h>
#include <strings.h>
@@ -35,6 +38,7 @@
#endif
#include <libgen.h>
#include <stddef.h>
+#include <sys/sysmacros.h>
#include <dt_impl.h>
#include <dt_program.h>
@@ -43,6 +47,7 @@
#if !defined(sun)
#include <libproc_compat.h>
#endif
+#include <dt_module.h>
typedef struct dt_pid_probe {
dtrace_hdl_t *dpp_dtp;
@@ -827,3 +832,170 @@ dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr)
return (ret);
}
+
+/*
+ * libdtrace has a backroom deal with us to ask us for type information on
+ * behalf of pid provider probes when fasttrap doesn't return any type
+ * information. Instead we'll look up the module and see if there is type
+ * information available. However, if there is no type information available due
+ * to a lack of CTF data, then we want to make sure that DTrace still carries on
+ * in face of that. As such we don't have a meaningful exit code about failure.
+ * We emit information about why we failed to the dtrace debug log so someone
+ * can figure it out by asking nicely for DTRACE_DEBUG.
+ */
+void
+dt_pid_get_types(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
+ dtrace_argdesc_t *adp, int *nargs)
+{
+ dt_module_t *dmp;
+ ctf_file_t *fp;
+ ctf_funcinfo_t f;
+ ctf_id_t argv[32];
+ GElf_Sym sym;
+#if defined(sun)
+ prsyminfo_t si;
+#else
+ void *si;
+#endif
+ struct ps_prochandle *p;
+ int i, args;
+ char buf[DTRACE_ARGTYPELEN];
+ const char *mptr;
+ char *eptr;
+ int ret = 0;
+ int argc = sizeof (argv) / sizeof (ctf_id_t);
+ Lmid_t lmid;
+
+ /* Set up a potential outcome */
+ args = *nargs;
+ *nargs = 0;
+
+ /*
+ * If we don't have an entry or return probe then we can just stop right
+ * now as we don't have arguments for offset probes.
+ */
+ if (strcmp(pdp->dtpd_name, "entry") != 0 &&
+ strcmp(pdp->dtpd_name, "return") != 0)
+ return;
+
+ dmp = dt_module_create(dtp, pdp->dtpd_provider);
+ if (dmp == NULL) {
+ dt_dprintf("failed to find module for %s\n",
+ pdp->dtpd_provider);
+ return;
+ }
+ if (dt_module_load(dtp, dmp) != 0) {
+ dt_dprintf("failed to load module for %s\n",
+ pdp->dtpd_provider);
+ return;
+ }
+
+ /*
+ * We may be working with a module that doesn't have ctf. If that's the
+ * case then we just return now and move on with life.
+ */
+ fp = dt_module_getctflib(dtp, dmp, pdp->dtpd_mod);
+ if (fp == NULL) {
+ dt_dprintf("no ctf container for %s\n",
+ pdp->dtpd_mod);
+ return;
+ }
+ p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
+ if (p == NULL) {
+ dt_dprintf("failed to grab pid\n");
+ return;
+ }
+ dt_proc_lock(dtp, p);
+
+ /*
+ * Check to see if the D module has a link map ID and separate that out
+ * for properly interrogating libproc.
+ */
+ if ((mptr = strchr(pdp->dtpd_mod, '`')) != NULL) {
+ if (strlen(pdp->dtpd_mod) < 3) {
+ dt_dprintf("found weird modname with linkmap, "
+ "aborting: %s\n", pdp->dtpd_mod);
+ goto out;
+ }
+ if (pdp->dtpd_mod[0] != 'L' || pdp->dtpd_mod[1] != 'M') {
+ dt_dprintf("missing leading 'LM', "
+ "aborting: %s\n", pdp->dtpd_mod);
+ goto out;
+ }
+ errno = 0;
+ lmid = strtol(pdp->dtpd_mod + 2, &eptr, 16);
+ if (errno == ERANGE || eptr != mptr) {
+ dt_dprintf("failed to parse out lmid, aborting: %s\n",
+ pdp->dtpd_mod);
+ goto out;
+ }
+ mptr++;
+ } else {
+ mptr = pdp->dtpd_mod;
+ lmid = 0;
+ }
+
+ if (Pxlookup_by_name(p, lmid, mptr, pdp->dtpd_func,
+ &sym, &si) != 0) {
+ dt_dprintf("failed to find function %s in %s`%s\n",
+ pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
+ goto out;
+ }
+#if defined(sun)
+ if (ctf_func_info(fp, si.prs_id, &f) == CTF_ERR) {
+ dt_dprintf("failed to get ctf information for %s in %s`%s\n",
+ pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
+ goto out;
+ }
+#endif
+
+ (void) snprintf(buf, sizeof (buf), "%s`%s", pdp->dtpd_provider,
+ pdp->dtpd_mod);
+
+ if (strcmp(pdp->dtpd_name, "return") == 0) {
+ if (args < 2)
+ goto out;
+
+ bzero(adp, sizeof (dtrace_argdesc_t));
+ adp->dtargd_ndx = 0;
+ adp->dtargd_id = pdp->dtpd_id;
+ adp->dtargd_mapping = adp->dtargd_ndx;
+ /*
+ * We explicitly leave out the library here, we only care that
+ * it is some int. We are assuming that there is no ctf
+ * container in here that is lying about what an int is.
+ */
+ (void) snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
+ "user %s`%s", pdp->dtpd_provider, "int");
+ adp++;
+ bzero(adp, sizeof (dtrace_argdesc_t));
+ adp->dtargd_ndx = 1;
+ adp->dtargd_id = pdp->dtpd_id;
+ adp->dtargd_mapping = adp->dtargd_ndx;
+ ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
+ "userland ");
+ (void) ctf_type_qname(fp, f.ctc_return, adp->dtargd_native +
+ ret, DTRACE_ARGTYPELEN - ret, buf);
+ *nargs = 2;
+#if defined(sun)
+ } else {
+ if (ctf_func_args(fp, si.prs_id, argc, argv) == CTF_ERR)
+ goto out;
+
+ *nargs = MIN(args, f.ctc_argc);
+ for (i = 0; i < *nargs; i++, adp++) {
+ bzero(adp, sizeof (dtrace_argdesc_t));
+ adp->dtargd_ndx = i;
+ adp->dtargd_id = pdp->dtpd_id;
+ adp->dtargd_mapping = adp->dtargd_ndx;
+ ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
+ "userland ");
+ (void) ctf_type_qname(fp, argv[i], adp->dtargd_native +
+ ret, DTRACE_ARGTYPELEN - ret, buf);
+ }
+#endif
+ }
+out:
+ dt_proc_unlock(dtp, p);
+ dt_proc_release(dtp, p);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h
index 886e33d..4bf39c8 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h
@@ -24,12 +24,13 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#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>
@@ -57,6 +58,9 @@ extern int dt_pid_create_offset_probe(struct ps_prochandle *, dtrace_hdl_t *,
extern int dt_pid_create_glob_offset_probes(struct ps_prochandle *,
dtrace_hdl_t *, fasttrap_probe_spec_t *, const GElf_Sym *, const char *);
+extern void dt_pid_get_types(dtrace_hdl_t *, const dtrace_probedesc_t *,
+ dtrace_argdesc_t *, int *);
+
#ifdef __cplusplus
}
#endif
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
index ccfa3da..fb8ea16 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
@@ -647,12 +647,16 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
dt_printarg_t pa;
ctf_id_t id;
dt_module_t *dmp;
+ ctf_file_t *ctfp;
+ int libid;
/*
* 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.
+ * behavior. In the case of userland CTF modules this will actually be
+ * of the format (module`lib`id). This is due to the fact that those
+ * modules have multiple CTF containers which `lib` identifies.
*/
for (s = typename; *s != '\0' && *s != '`'; s++)
;
@@ -663,6 +667,20 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
object = alloca(s - typename + 1);
bcopy(typename, object, s - typename);
object[s - typename] = '\0';
+ dmp = dt_module_lookup_by_name(dtp, object);
+ if (dmp == NULL)
+ return (0);
+
+ if (dmp->dm_pid != 0) {
+ libid = atoi(s + 1);
+ s = strchr(s + 1, '`');
+ if (s == NULL || libid > dmp->dm_nctflibs)
+ return (0);
+ ctfp = dmp->dm_libctfp[libid];
+ } else {
+ ctfp = dt_module_getctf(dtp, dmp);
+ }
+
id = atoi(s + 1);
/*
@@ -670,16 +688,13 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
* 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) {
+ if (ctfp == NULL || ctf_type_kind(ctfp, id) == CTF_ERR)
return (0);
- }
/* setup the print structure and kick off the main print routine */
pa.pa_dtp = dtp;
pa.pa_addr = addr;
- pa.pa_ctfp = dt_module_getctf(dtp, dmp);
+ pa.pa_ctfp = ctfp;
pa.pa_nest = 0;
pa.pa_depth = 0;
pa.pa_file = fp;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
index 24682b2..9d4403c 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
@@ -21,8 +21,8 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, Joyent, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#if defined(sun)
@@ -1070,7 +1070,7 @@ dt_printf_validate(dt_pfargv_t *pfv, uint_t flags,
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);
+ dt_node_type_assign(&aggnode, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
for (i = 0, j = 0; i < pfv->pfv_argc; i++, pfd = pfd->pfd_next) {
const dt_pfconv_t *pfc = pfd->pfd_conv;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
index 188ce0e..0f1bfe0 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
@@ -23,8 +23,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include <sys/types.h>
#if defined(sun)
@@ -45,6 +46,8 @@
#include <dt_module.h>
#include <dt_string.h>
#include <dt_list.h>
+#include <dt_pid.h>
+#include <dtrace.h>
static dt_provider_t *
dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h)
@@ -273,6 +276,21 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp)
nc++;
/*
+ * The pid provider believes in giving the kernel a break. No reason to
+ * give the kernel all the ctf containers that we're keeping ourselves
+ * just to get it back from it. So if we're coming from a pid provider
+ * probe and the kernel gave us no argument information we'll get some
+ * here. If for some crazy reason the kernel knows about our userland
+ * types then we just ignore this.
+ */
+ if (xc == 0 && nc == 0 &&
+ strncmp(pvp->pv_desc.dtvd_name, "pid", 3) == 0) {
+ nc = adc;
+ dt_pid_get_types(dtp, pdp, adv, &nc);
+ xc = 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.
@@ -318,7 +336,8 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp)
dtt.dtt_type = CTF_ERR;
} else {
dt_node_type_assign(prp->pr_nargv[adp->dtargd_mapping],
- dtt.dtt_ctfp, dtt.dtt_type);
+ dtt.dtt_ctfp, dtt.dtt_type,
+ dtt.dtt_flags & DTT_FL_USER ? B_TRUE : B_FALSE);
}
if (dtt.dtt_type != CTF_ERR && (adp->dtargd_xlate[0] == '\0' ||
@@ -337,7 +356,7 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp)
dtt.dtt_type = CTF_ERR;
} else {
dt_node_type_assign(prp->pr_xargv[i],
- dtt.dtt_ctfp, dtt.dtt_type);
+ dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
}
prp->pr_mapping[i] = adp->dtargd_mapping;
@@ -638,7 +657,7 @@ dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp)
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_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
dt_node_attr_assign(dnp, _dtrace_defattr);
return (dnp);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c
index 7ac0cc4..74bd487 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c
@@ -23,8 +23,10 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ */
#include <strings.h>
#include <assert.h>
@@ -69,7 +71,7 @@ dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
enp->dn_op = DT_TOK_XLATE;
enp->dn_xlator = dxp;
enp->dn_xmember = mnp;
- dt_node_type_assign(enp, dxp->dx_dst_ctfp, type);
+ dt_node_type_assign(enp, dxp->dx_dst_ctfp, type, B_FALSE);
/*
* For the member itself, we use a DT_NODE_MEMBER as usual with the
@@ -83,7 +85,7 @@ dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
mnp->dn_membname = strdup(name);
mnp->dn_membexpr = enp;
- dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type);
+ dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type, B_FALSE);
if (mnp->dn_membname == NULL)
return (dt_set_errno(dtp, EDT_NOMEM));
@@ -318,7 +320,8 @@ dt_xlator_lookup(dtrace_hdl_t *dtp, dt_node_t *src, dt_node_t *dst, int flags)
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);
+ dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type,
+ B_FALSE);
if (ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
dst_ctfp, dst_base) && dt_node_is_argcompat(src, &xn))
goto out;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
index b2e3108..6f88e6d 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
@@ -25,7 +25,8 @@
*/
/*
- * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#ifndef _DTRACE_H
@@ -356,6 +357,12 @@ extern int dtrace_handle_setopt(dtrace_hdl_t *,
#define DTRACE_A_PERCPU 0x0001
#define DTRACE_A_KEEPDELTA 0x0002
#define DTRACE_A_ANONYMOUS 0x0004
+#define DTRACE_A_TOTAL 0x0008
+#define DTRACE_A_MINMAXBIN 0x0010
+#define DTRACE_A_HASNEGATIVES 0x0020
+#define DTRACE_A_HASPOSITIVES 0x0040
+
+#define DTRACE_AGGZOOM_MAX 0.95 /* height of max bar */
#define DTRACE_AGGWALK_ERROR -1 /* error while processing */
#define DTRACE_AGGWALK_NEXT 0 /* proceed to next element */
@@ -376,6 +383,10 @@ struct dtrace_aggdata {
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 */
+ int64_t dtada_total; /* per agg total, if avail */
+ uint16_t dtada_minbin; /* minimum bin, if avail */
+ uint16_t dtada_maxbin; /* maximum bin, if avail */
+ uint32_t dtada_flags; /* flags */
};
typedef int dtrace_aggregate_f(const dtrace_aggdata_t *, void *);
@@ -495,8 +506,11 @@ 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 */
+ uint_t dtt_flags; /* Misc. flags */
} dtrace_typeinfo_t;
+#define DTT_FL_USER 0x1 /* user type */
+
extern int dtrace_lookup_by_type(dtrace_hdl_t *, const char *, const char *,
dtrace_typeinfo_t *);
diff --git a/cddl/lib/libdtrace/libproc_compat.h b/cddl/lib/libdtrace/libproc_compat.h
index a561157..2083d8b 100644
--- a/cddl/lib/libdtrace/libproc_compat.h
+++ b/cddl/lib/libdtrace/libproc_compat.h
@@ -45,8 +45,10 @@
#define Pgrab_error strerror
#define Plmid_to_map(p, l, o) proc_obj2map((p), (o))
#define Plookup_by_addr proc_addr2sym
+#define Pname_to_ctf(p, obj) NULL
#define Pname_to_map proc_name2map
#define Pobject_iter proc_iter_objs
+#define Pobject_iter_resolved(p, f, arg) 1
#define Pobjname proc_objname
#define Pread proc_read
#define Prd_agent proc_rdagent
OpenPOWER on IntegriCloud