1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * This file defines the standard set of inlines and translators to be made
29  * available for all D programs to use to examine process model state.
30  */
31 
32 #pragma D depends_on module procfs
33 
34 /*
35  * The following miscellaneous constants are used by the proc(4) translators
36  * defined below.  These are assigned the latest values from the system .h's.
37  */
38 inline char SSLEEP = 1;
39 #pragma D binding "1.0" SSLEEP
40 inline char SRUN = 2;
41 #pragma D binding "1.0" SRUN
42 inline char SZOMB = 3;
43 #pragma D binding "1.0" SZOMB
44 inline char SSTOP = 4;
45 #pragma D binding "1.0" SSTOP
46 inline char SIDL = 5;
47 #pragma D binding "1.0" SIDL
48 inline char SONPROC = 6;
49 #pragma D binding "1.0" SONPROC
50 inline char SWAIT = 7;
51 #pragma D binding "1.0" SWAIT
52 
53 inline int PR_STOPPED = 0x00000001;
54 #pragma D binding "1.0" PR_STOPPED
55 inline int PR_ISTOP = 0x00000002;
56 #pragma D binding "1.0" PR_ISTOP
57 inline int PR_DSTOP = 0x00000004;
58 #pragma D binding "1.0" PR_DSTOP
59 inline int PR_STEP = 0x00000008;
60 #pragma D binding "1.0" PR_STEP
61 inline int PR_ASLEEP = 0x00000010;
62 #pragma D binding "1.0" PR_ASLEEP
63 inline int PR_PCINVAL = 0x00000020;
64 #pragma D binding "1.0" PR_PCINVAL
65 inline int PR_ASLWP = 0x00000040;
66 #pragma D binding "1.0" PR_ASLWP
67 inline int PR_AGENT = 0x00000080;
68 #pragma D binding "1.0" PR_AGENT
69 inline int PR_DETACH = 0x00000100;
70 #pragma D binding "1.0" PR_DETACH
71 inline int PR_DAEMON = 0x00000200;
72 #pragma D binding "1.0" PR_DAEMON
73 inline int PR_IDLE = 0x00000400;
74 #pragma D binding "1.4" PR_IDLE
75 inline int PR_ISSYS = 0x00001000;
76 #pragma D binding "1.0" PR_ISSYS
77 inline int PR_VFORKP = 0x00002000;
78 #pragma D binding "1.0" PR_VFORKP
79 inline int PR_ORPHAN = 0x00004000;
80 #pragma D binding "1.0" PR_ORPHAN
81 inline int PR_NOSIGCHLD = 0x00008000;
82 #pragma D binding "1.4" PR_NOSIGCHLD
83 inline int PR_WAITPID = 0x00010000;
84 #pragma D binding "1.4" PR_WAITPID
85 inline int PR_FORK = 0x00100000;
86 #pragma D binding "1.0" PR_FORK
87 inline int PR_RLC = 0x00200000;
88 #pragma D binding "1.0" PR_RLC
89 inline int PR_KLC = 0x00400000;
90 #pragma D binding "1.0" PR_KLC
91 inline int PR_ASYNC = 0x00800000;
92 #pragma D binding "1.0" PR_ASYNC
93 inline int PR_MSACCT = 0x01000000;
94 #pragma D binding "1.0" PR_MSACCT
95 inline int PR_BPTADJ = 0x02000000;
96 #pragma D binding "1.0" PR_BPTADJ
97 inline int PR_PTRACE = 0x04000000;
98 #pragma D binding "1.0" PR_PTRACE
99 inline int PR_MSFORK = 0x08000000;
100 #pragma D binding "1.0" PR_MSFORK
101 
102 inline char PR_MODEL_ILP32 = 1;
103 #pragma D binding "1.0" PR_MODEL_ILP32
104 inline char PR_MODEL_LP64 = 2;
105 #pragma D binding "1.0" PR_MODEL_LP64
106 
107 inline char SOBJ_NONE = 0;
108 #pragma D binding "1.0" SOBJ_NONE
109 inline char SOBJ_MUTEX = 1;
110 #pragma D binding "1.0" SOBJ_MUTEX
111 inline char SOBJ_RWLOCK = 2;
112 #pragma D binding "1.0" SOBJ_RWLOCK
113 inline char SOBJ_CV = 3;
114 #pragma D binding "1.0" SOBJ_CV
115 inline char SOBJ_SEMA = 4;
116 #pragma D binding "1.0" SOBJ_SEMA
117 inline char SOBJ_USER = 5;
118 #pragma D binding "1.0" SOBJ_USER
119 inline char SOBJ_USER_PI = 6;
120 #pragma D binding "1.0" SOBJ_USER_PI
121 inline char SOBJ_SHUTTLE = 7;
122 #pragma D binding "1.0" SOBJ_SHUTTLE
123 
124 inline int SI_USER = 0;
125 #pragma D binding "1.0" SI_USER
126 inline int SI_LWP = (-1);
127 #pragma D binding "1.0" SI_LWP
128 inline int SI_QUEUE = (-2);
129 #pragma D binding "1.0" SI_QUEUE
130 inline int SI_TIMER = (-3);
131 #pragma D binding "1.0" SI_TIMER
132 inline int SI_ASYNCIO = (-4);
133 #pragma D binding "1.0" SI_ASYNCIO
134 inline int SI_MESGQ = (-5);
135 #pragma D binding "1.0" SI_MESGQ
136 inline int SI_RCTL = 2049;
137 #pragma D binding "1.0" SI_RCTL
138 inline int ILL_ILLOPC = 1;
139 #pragma D binding "1.0" ILL_ILLOPC
140 inline int ILL_ILLOPN = 2;
141 #pragma D binding "1.0" ILL_ILLOPN
142 inline int ILL_ILLADR = 3;
143 #pragma D binding "1.0" ILL_ILLADR
144 inline int ILL_ILLTRP = 4;
145 #pragma D binding "1.0" ILL_ILLTRP
146 inline int ILL_PRVOPC = 5;
147 #pragma D binding "1.0" ILL_PRVOPC
148 inline int ILL_PRVREG = 6;
149 #pragma D binding "1.0" ILL_PRVREG
150 inline int ILL_COPROC = 7;
151 #pragma D binding "1.0" ILL_COPROC
152 inline int ILL_BADSTK = 8;
153 #pragma D binding "1.0" ILL_BADSTK
154 inline int FPE_INTDIV = 1;
155 #pragma D binding "1.0" FPE_INTDIV
156 inline int FPE_INTOVF = 2;
157 #pragma D binding "1.0" FPE_INTOVF
158 inline int FPE_FLTDIV = 3;
159 #pragma D binding "1.0" FPE_FLTDIV
160 inline int FPE_FLTOVF = 4;
161 #pragma D binding "1.0" FPE_FLTOVF
162 inline int FPE_FLTUND = 5;
163 #pragma D binding "1.0" FPE_FLTUND
164 inline int FPE_FLTRES = 6;
165 #pragma D binding "1.0" FPE_FLTRES
166 inline int FPE_FLTINV = 7;
167 #pragma D binding "1.0" FPE_FLTINV
168 inline int FPE_FLTSUB = 8;
169 #pragma D binding "1.0" FPE_FLTSUB
170 inline int SEGV_MAPERR = 1;
171 #pragma D binding "1.0" SEGV_MAPERR
172 inline int SEGV_ACCERR = 2;
173 #pragma D binding "1.0" SEGV_ACCERR
174 inline int BUS_ADRALN = 1;
175 #pragma D binding "1.0" BUS_ADRALN
176 inline int BUS_ADRERR = 2;
177 #pragma D binding "1.0" BUS_ADRERR
178 inline int BUS_OBJERR = 3;
179 #pragma D binding "1.0" BUS_OBJERR
180 inline int TRAP_BRKPT = 1;
181 #pragma D binding "1.0" TRAP_BRKPT
182 inline int TRAP_TRACE = 2;
183 #pragma D binding "1.0" TRAP_TRACE
184 inline int CLD_EXITED = 1;
185 #pragma D binding "1.0" CLD_EXITED
186 inline int CLD_KILLED = 2;
187 #pragma D binding "1.0" CLD_KILLED
188 inline int CLD_DUMPED = 3;
189 #pragma D binding "1.0" CLD_DUMPED
190 inline int CLD_TRAPPED = 4;
191 #pragma D binding "1.0" CLD_TRAPPED
192 inline int CLD_STOPPED = 5;
193 #pragma D binding "1.0" CLD_STOPPED
194 inline int CLD_CONTINUED = 6;
195 #pragma D binding "1.0" CLD_CONTINUED
196 inline int POLL_IN = 1;
197 #pragma D binding "1.0" POLL_IN
198 inline int POLL_OUT = 2;
199 #pragma D binding "1.0" POLL_OUT
200 inline int POLL_MSG = 3;
201 #pragma D binding "1.0" POLL_MSG
202 inline int POLL_ERR = 4;
203 #pragma D binding "1.0" POLL_ERR
204 inline int POLL_PRI = 5;
205 #pragma D binding "1.0" POLL_PRI
206 inline int POLL_HUP = 6;
207 #pragma D binding "1.0" POLL_HUP
208 
209 /*
210  * Translate from the kernel's proc_t structure to a proc(4) psinfo_t struct.
211  * We do not provide support for pr_size, pr_rssize, pr_pctcpu, and pr_pctmem.
212  * We also do not fill in pr_lwp (the lwpsinfo_t for the representative LWP)
213  * because we do not have the ability to select and stop any representative.
214  * Also, for the moment, pr_wstat, pr_time, and pr_ctime are not supported,
215  * but these could be supported by DTrace in the future using subroutines.
216  * Note that any member added to this translator should also be added to the
217  * kthread_t-to-psinfo_t translator, below.
218  */
219 #pragma D binding "1.0" translator
220 translator psinfo_t < proc_t *T > {
221 	pr_nlwp = T->p_lwpcnt;
222 	pr_pid = T->p_pidp->pid_id;
223 	pr_ppid = T->p_ppid;
224 	pr_pgid = T->p_pgidp->pid_id;
225 	pr_sid = T->p_sessp->s_sidp->pid_id;
226 	pr_uid = T->p_cred->cr_ruid;
227 	pr_euid = T->p_cred->cr_uid;
228 	pr_gid = T->p_cred->cr_rgid;
229 	pr_egid = T->p_cred->cr_gid;
230 	pr_addr = (uintptr_t)T;
231 
232 	pr_ttydev = (T->p_sessp->s_vp == NULL) ? (dev_t)-1 :
233 	    (T->p_sessp->s_dev == `rwsconsdev) ? `uconsdev :
234 	    (T->p_sessp->s_dev == `rconsdev) ? `uconsdev : T->p_sessp->s_dev;
235 
236 	pr_start = T->p_user.u_start;
237 	pr_fname = T->p_user.u_comm;
238 	pr_psargs = T->p_user.u_psargs;
239 	pr_argc = T->p_user.u_argc;
240 	pr_argv = T->p_user.u_argv;
241 	pr_envp = T->p_user.u_envp;
242 
243 	pr_dmodel = (T->p_model == 0x00100000) ?
244 	    PR_MODEL_ILP32 : PR_MODEL_LP64;
245 
246 	pr_taskid = T->p_task->tk_tkid;
247 	pr_projid = T->p_task->tk_proj->kpj_id;
248 	pr_poolid = T->p_pool->pool_id;
249 	pr_zoneid = T->p_zone->zone_id;
250 	pr_contract = (T->p_ct_process == NULL) ? -1 :
251 	    T->p_ct_process->conp_contract.ct_id;
252 };
253 
254 /*
255  * Translate from the kernel's kthread_t structure to a proc(4) psinfo_t
256  * struct.  Lacking a facility to define one translator only in terms of
257  * another, we explicitly define each member by using the proc_t-to-psinfo_t
258  * translator, above; any members added to that translator should also be
259  * added here.  (The only exception to this is pr_start, which -- due to it
260  * being a structure -- cannot be defined in terms of a translator at all.)
261  */
262 #pragma D binding "1.0" translator
263 translator psinfo_t < kthread_t *T > {
264 	pr_nlwp = xlate <psinfo_t> (T->t_procp).pr_nlwp;
265 	pr_pid = xlate <psinfo_t> (T->t_procp).pr_pid;
266 	pr_ppid = xlate <psinfo_t> (T->t_procp).pr_ppid;
267 	pr_pgid = xlate <psinfo_t> (T->t_procp).pr_pgid;
268 	pr_sid = xlate <psinfo_t> (T->t_procp).pr_sid;
269 	pr_uid = xlate <psinfo_t> (T->t_procp).pr_uid;
270 	pr_euid = xlate <psinfo_t> (T->t_procp).pr_euid;
271 	pr_gid = xlate <psinfo_t> (T->t_procp).pr_gid;
272 	pr_egid = xlate <psinfo_t> (T->t_procp).pr_egid;
273 	pr_addr = xlate <psinfo_t> (T->t_procp).pr_addr;
274 	pr_ttydev = xlate <psinfo_t> (T->t_procp).pr_ttydev;
275 	pr_start = (timestruc_t)xlate <psinfo_t> (T->t_procp).pr_start;
276 	pr_fname = xlate <psinfo_t> (T->t_procp).pr_fname;
277 	pr_psargs = xlate <psinfo_t> (T->t_procp).pr_psargs;
278 	pr_argc = xlate <psinfo_t> (T->t_procp).pr_argc;
279 	pr_argv = xlate <psinfo_t> (T->t_procp).pr_argv;
280 	pr_envp = xlate <psinfo_t> (T->t_procp).pr_envp;
281 	pr_dmodel = xlate <psinfo_t> (T->t_procp).pr_dmodel;
282 	pr_taskid = xlate <psinfo_t> (T->t_procp).pr_taskid;
283 	pr_projid = xlate <psinfo_t> (T->t_procp).pr_projid;
284 	pr_poolid = xlate <psinfo_t> (T->t_procp).pr_poolid;
285 	pr_zoneid = xlate <psinfo_t> (T->t_procp).pr_zoneid;
286 	pr_contract = xlate <psinfo_t> (T->t_procp).pr_contract;
287 };
288 
289 /*
290  * Translate from the kernel's kthread_t structure to a proc(4) lwpsinfo_t.
291  * We do not provide support for pr_nice, pr_oldpri, pr_cpu, or pr_pctcpu.
292  * Also, for the moment, pr_start and pr_time are not supported, but these
293  * could be supported by DTrace in the future using subroutines.
294  */
295 #pragma D binding "1.0" translator
296 translator lwpsinfo_t < kthread_t *T > {
297 	pr_flag = ((T->t_state == 0x10) ? (PR_STOPPED |
298 	    ((!(T->t_schedflag & 0x0800)) ? PR_ISTOP : 0)) :
299 	    ((T->t_proc_flag & 0x0080) ? PR_STOPPED | PR_ISTOP : 0)) |
300 	    ((T == T->t_procp->p_agenttp) ? PR_AGENT : 0) |
301 	    ((!(T->t_proc_flag & 0x0004)) ? PR_DETACH : 0) |
302 	    ((T->t_proc_flag & 0x0001) ? PR_DAEMON : 0) |
303 	    ((T->t_procp->p_pidflag & 0x0004) ? PR_NOSIGCHLD : 0) |
304 	    ((T->t_procp->p_pidflag & 0x0008) ? PR_WAITPID : 0) |
305 	    ((T->t_procp->p_proc_flag & 0x0004) ? PR_FORK : 0) |
306 	    ((T->t_procp->p_proc_flag & 0x0080) ? PR_RLC : 0) |
307 	    ((T->t_procp->p_proc_flag & 0x0100) ? PR_KLC : 0) |
308 	    ((T->t_procp->p_proc_flag & 0x0010) ? PR_ASYNC : 0) |
309 	    ((T->t_procp->p_proc_flag & 0x0040) ? PR_BPTADJ : 0) |
310 	    ((T->t_procp->p_proc_flag & 0x0002) ? PR_PTRACE : 0) |
311 	    ((T->t_procp->p_flag & 0x02000000) ? PR_MSACCT : 0) |
312 	    ((T->t_procp->p_flag & 0x40000000) ? PR_MSFORK : 0) |
313 	    ((T->t_procp->p_flag & 0x00080000) ? PR_VFORKP : 0) |
314 	    (((T->t_procp->p_flag & 0x00000001) ||
315 	    (T->t_procp->p_as == &`kas)) ? PR_ISSYS : 0) |
316 	    ((T == T->t_cpu->cpu_idle_thread) ? PR_IDLE : 0);
317 
318 	pr_lwpid = T->t_tid;
319 	pr_addr = (uintptr_t)T;
320 	pr_wchan = (uintptr_t)T->t_lwpchan.lc_wchan;
321 	pr_stype = T->t_sobj_ops ? T->t_sobj_ops->sobj_type : 0;
322 
323 	pr_state = (T->t_proc_flag & 0x0080) ? SSTOP :
324 	    (T->t_state == 0x01) ? SSLEEP :
325 	    (T->t_state == 0x02) ? SRUN :
326 	    (T->t_state == 0x04) ? SONPROC :
327 	    (T->t_state == 0x08) ? SZOMB :
328 	    (T->t_state == 0x10) ? SSTOP :
329 	    (T->t_state == 0x20) ? SWAIT : 0;
330 
331 	pr_sname = (T->t_proc_flag & 0x0080) ? 'T' :
332 	    (T->t_state == 0x01) ? 'S' :
333 	    (T->t_state == 0x02) ? 'R' :
334 	    (T->t_state == 0x04) ? 'O' :
335 	    (T->t_state == 0x08) ? 'Z' :
336 	    (T->t_state == 0x10) ? 'T' :
337 	    (T->t_state == 0x20) ? 'W' : '?';
338 
339 	pr_syscall = T->t_sysnum;
340 	pr_pri = T->t_pri;
341 	pr_clname = `sclass[T->t_cid].cl_name;
342 	pr_onpro = T->t_cpu->cpu_id;
343 	pr_bindpro = T->t_bind_cpu;
344 	pr_bindpset = T->t_bind_pset;
345 	pr_lgrp = T->t_lpl->lpl_lgrpid;
346 };
347 
348 inline psinfo_t *curpsinfo = xlate <psinfo_t *> (curthread->t_procp);
349 #pragma D attributes Stable/Stable/Common curpsinfo
350 #pragma D binding "1.0" curpsinfo
351 
352 inline lwpsinfo_t *curlwpsinfo = xlate <lwpsinfo_t *> (curthread);
353 #pragma D attributes Stable/Stable/Common curlwpsinfo
354 #pragma D binding "1.0" curlwpsinfo
355 
356 inline string cwd = curthread->t_procp->p_user.u_cdir->v_path == NULL ?
357     "<unknown>" : stringof(curthread->t_procp->p_user.u_cdir->v_path);
358 #pragma D attributes Stable/Stable/Common cwd
359 #pragma D binding "1.0" cwd
360 
361 inline string root = curthread->t_procp->p_user.u_rdir == NULL ? "/" :
362     curthread->t_procp->p_user.u_rdir->v_path == NULL ? "<unknown>" :
363     stringof(curthread->t_procp->p_user.u_rdir->v_path);
364 #pragma D attributes Stable/Stable/Common root
365 #pragma D binding "1.0" root
366