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