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