1 /* This file is concerned with the IPC server, not with kernel-level IPC. */
10 put_key(struct trace_proc
* proc
, const char * name
, key_t key
)
13 if (!valuesonly
&& key
== IPC_PRIVATE
)
14 put_field(proc
, name
, "IPC_PRIVATE");
16 put_value(proc
, name
, "%ld", key
);
19 static const struct flags ipcget_flags
[] = {
25 ipc_shmget_out(struct trace_proc
* proc
, const message
* m_out
)
28 put_key(proc
, "key", m_out
->m_lc_ipc_shmget
.key
);
29 put_value(proc
, "size", "%zu", m_out
->m_lc_ipc_shmget
.size
);
30 put_flags(proc
, "shmflg", ipcget_flags
, COUNT(ipcget_flags
), "0%o",
31 m_out
->m_lc_ipc_shmget
.flag
);
37 ipc_shmget_in(struct trace_proc
* proc
, const message
* __unused m_out
,
38 const message
* m_in
, int failed
)
42 put_value(proc
, NULL
, "%d", m_in
->m_lc_ipc_shmget
.retid
);
47 static const struct flags shmat_flags
[] = {
53 ipc_shmat_out(struct trace_proc
* proc
, const message
* m_out
)
56 put_value(proc
, "shmid", "%d", m_out
->m_lc_ipc_shmat
.id
);
57 put_ptr(proc
, "shmaddr", (vir_bytes
)m_out
->m_lc_ipc_shmat
.addr
);
58 put_flags(proc
, "shmflg", shmat_flags
, COUNT(shmat_flags
), "0x%x",
59 m_out
->m_lc_ipc_shmat
.flag
);
65 ipc_shmat_in(struct trace_proc
* proc
, const message
* __unused m_out
,
66 const message
* m_in
, int failed
)
70 put_ptr(proc
, NULL
, (vir_bytes
)m_in
->m_lc_ipc_shmat
.retaddr
);
76 ipc_shmdt_out(struct trace_proc
* proc
, const message
* m_out
)
79 put_ptr(proc
, "shmaddr", (vir_bytes
)m_out
->m_lc_ipc_shmdt
.addr
);
85 put_shmctl_cmd(struct trace_proc
* proc
, const char * name
, int cmd
)
87 const char *text
= NULL
;
101 put_field(proc
, name
, text
);
103 put_value(proc
, name
, "%d", cmd
);
106 static const struct flags shm_mode_flags
[] = {
112 put_struct_shmid_ds(struct trace_proc
* proc
, const char * name
, int flags
,
118 if (!put_open_struct(proc
, name
, flags
, addr
, &buf
, sizeof(buf
)))
121 /* Is this an IPC_SET call? Then print a small subset of fields.. */
122 set
= (flags
& PF_ALT
);
124 put_open(proc
, "shm_perm", 0, "{", ", ");
126 put_value(proc
, "uid", "%u", buf
.shm_perm
.uid
);
127 put_value(proc
, "gid", "%u", buf
.shm_perm
.gid
);
128 if (!set
&& verbose
> 0) {
129 put_value(proc
, "cuid", "%u", buf
.shm_perm
.cuid
);
130 put_value(proc
, "cgid", "%u", buf
.shm_perm
.cgid
);
132 put_flags(proc
, "mode", shm_mode_flags
, COUNT(shm_mode_flags
),
133 "0%03o", buf
.shm_perm
.mode
);
135 put_close(proc
, "}");
138 put_value(proc
, "shm_segsz", "%zu", buf
.shm_segsz
);
140 put_value(proc
, "shm_lpid", "%d", buf
.shm_lpid
);
141 put_value(proc
, "shm_cpid", "%d", buf
.shm_cpid
);
142 put_time(proc
, "shm_atime", buf
.shm_atime
);
143 put_time(proc
, "shm_dtime", buf
.shm_dtime
);
144 put_time(proc
, "shm_ctime", buf
.shm_ctime
);
146 put_value(proc
, "shm_nattch", "%u", buf
.shm_nattch
);
149 put_close_struct(proc
, set
|| verbose
> 0);
153 ipc_shmctl_out(struct trace_proc
* proc
, const message
* m_out
)
156 put_value(proc
, "shmid", "%d", m_out
->m_lc_ipc_shmctl
.id
);
157 put_shmctl_cmd(proc
, "cmd", m_out
->m_lc_ipc_shmctl
.cmd
);
159 /* TODO: add support for the IPC_INFO and SHM_INFO structures.. */
160 switch (m_out
->m_lc_ipc_shmctl
.cmd
) {
166 put_struct_shmid_ds(proc
, "buf", PF_ALT
,
167 (vir_bytes
)m_out
->m_lc_ipc_shmctl
.buf
);
172 put_ptr(proc
, "buf", (vir_bytes
)m_out
->m_lc_ipc_shmctl
.buf
);
179 ipc_shmctl_in(struct trace_proc
* proc
, const message
* m_out
,
180 const message
* m_in
, int failed
)
183 switch (m_out
->m_lc_ipc_shmctl
.cmd
) {
186 put_struct_shmid_ds(proc
, "buf", failed
,
187 (vir_bytes
)m_out
->m_lc_ipc_shmctl
.buf
);
194 switch (m_out
->m_lc_ipc_shmctl
.cmd
) {
198 put_value(proc
, NULL
, "%d", m_in
->m_lc_ipc_shmctl
.ret
);
208 ipc_semget_out(struct trace_proc
* proc
, const message
* m_out
)
211 put_key(proc
, "key", m_out
->m_lc_ipc_semget
.key
);
212 put_value(proc
, "nsems", "%d", m_out
->m_lc_ipc_semget
.nr
);
213 put_flags(proc
, "semflg", ipcget_flags
, COUNT(ipcget_flags
), "0%o",
214 m_out
->m_lc_ipc_semget
.flag
);
220 ipc_semget_in(struct trace_proc
* proc
, const message
* __unused m_out
,
221 const message
* m_in
, int failed
)
225 put_value(proc
, NULL
, "%d", m_in
->m_lc_ipc_semget
.retid
);
231 put_semctl_cmd(struct trace_proc
* proc
, const char * name
, int cmd
)
233 const char *text
= NULL
;
254 put_field(proc
, name
, text
);
256 put_value(proc
, name
, "%d", cmd
);
260 put_struct_semid_ds(struct trace_proc
* proc
, const char * name
, int flags
,
266 if (!put_open_struct(proc
, name
, flags
, addr
, &buf
, sizeof(buf
)))
269 /* Is this an IPC_SET call? Then print a small subset of fields.. */
270 set
= (flags
& PF_ALT
);
272 put_open(proc
, "sem_perm", 0, "{", ", ");
274 put_value(proc
, "uid", "%u", buf
.sem_perm
.uid
);
275 put_value(proc
, "gid", "%u", buf
.sem_perm
.gid
);
276 if (!set
&& verbose
> 0) {
277 put_value(proc
, "cuid", "%u", buf
.sem_perm
.cuid
);
278 put_value(proc
, "cgid", "%u", buf
.sem_perm
.cgid
);
280 put_value(proc
, "mode", "0%03o", buf
.sem_perm
.mode
);
282 put_close(proc
, "}");
286 put_time(proc
, "sem_otime", buf
.sem_otime
);
287 put_time(proc
, "sem_ctime", buf
.sem_ctime
);
289 put_value(proc
, "sem_nsems", "%u", buf
.sem_nsems
);
292 put_close_struct(proc
, set
|| verbose
> 0);
297 ipc_semctl_out(struct trace_proc
* proc
, const message
* m_out
)
300 put_value(proc
, "semid", "%d", m_out
->m_lc_ipc_semctl
.id
);
301 put_value(proc
, "semnum", "%d", m_out
->m_lc_ipc_semctl
.num
);
302 put_semctl_cmd(proc
, "cmd", m_out
->m_lc_ipc_semctl
.cmd
);
304 /* TODO: add support for the IPC_INFO and SEM_INFO structures.. */
305 switch (m_out
->m_lc_ipc_semctl
.cmd
) {
311 put_struct_semid_ds(proc
, "buf", PF_ALT
,
312 (vir_bytes
)m_out
->m_lc_ipc_semctl
.opt
);
318 put_ptr(proc
, "buf", (vir_bytes
)m_out
->m_lc_ipc_semctl
.opt
);
324 put_ptr(proc
, "array", (vir_bytes
)m_out
->m_lc_ipc_semctl
.opt
);
329 put_value(proc
, "val", "%lu", m_out
->m_lc_ipc_semctl
.opt
);
339 ipc_semctl_in(struct trace_proc
* proc
, const message
* m_out
,
340 const message
* m_in
, int failed
)
343 switch (m_out
->m_lc_ipc_semctl
.cmd
) {
346 put_struct_semid_ds(proc
, "buf", failed
,
347 (vir_bytes
)m_out
->m_lc_ipc_semctl
.opt
);
354 switch (m_out
->m_lc_ipc_semctl
.cmd
) {
362 put_value(proc
, NULL
, "%d", m_in
->m_lc_ipc_semctl
.ret
);
369 static const struct flags sem_flags
[] = {
375 put_struct_sembuf(struct trace_proc
* proc
, const char * name
, int flags
,
381 if (!put_open_struct(proc
, name
, flags
, addr
, &buf
, sizeof(buf
)))
385 put_value(proc
, "sem_num", "%u", buf
.sem_num
);
386 put_value(proc
, "sem_op", "%d", buf
.sem_op
);
387 if (verbose
> 0 || (buf
.sem_flg
& ~SEM_UNDO
) != 0) {
388 put_flags(proc
, "sem_flg", sem_flags
, COUNT(sem_flags
), "0x%x",
393 put_close_struct(proc
, all
);
397 put_sembuf_array(struct trace_proc
* proc
, const char * name
, vir_bytes addr
,
400 struct sembuf buf
[SEMOPM
]; /* about 600 bytes, so OK for the stack */
403 if (valuesonly
> 1 || count
> SEMOPM
||
404 mem_get_data(proc
->pid
, addr
, &buf
, count
* sizeof(buf
[0])) != 0) {
405 put_ptr(proc
, name
, addr
);
410 put_open(proc
, name
, PF_NONAME
, "[", ", ");
411 for (i
= 0; i
< count
; i
++)
412 put_struct_sembuf(proc
, NULL
, PF_LOCADDR
, (vir_bytes
)&buf
[i
]);
413 put_close(proc
, "]");
417 ipc_semop_out(struct trace_proc
* proc
, const message
* m_out
)
420 put_value(proc
, "semid", "%d", m_out
->m_lc_ipc_semop
.id
);
421 put_sembuf_array(proc
, "sops", (vir_bytes
)m_out
->m_lc_ipc_semop
.ops
,
422 m_out
->m_lc_ipc_semop
.size
);
423 put_value(proc
, "nsops", "%u", m_out
->m_lc_ipc_semop
.size
);
428 #define IPC_CALL(c) [((IPC_ ## c) - IPC_BASE)]
430 static const struct call_handler ipc_map
[] = {
431 IPC_CALL(SHMGET
) = HANDLER("shmget", ipc_shmget_out
, ipc_shmget_in
),
432 IPC_CALL(SHMAT
) = HANDLER("shmat", ipc_shmat_out
, ipc_shmat_in
),
433 IPC_CALL(SHMDT
) = HANDLER("shmdt", ipc_shmdt_out
, default_in
),
434 IPC_CALL(SHMCTL
) = HANDLER("shmctl", ipc_shmctl_out
, ipc_shmctl_in
),
435 IPC_CALL(SEMGET
) = HANDLER("semget", ipc_semget_out
, ipc_semget_in
),
436 IPC_CALL(SEMCTL
) = HANDLER("semctl", ipc_semctl_out
, ipc_semctl_in
),
437 IPC_CALL(SEMOP
) = HANDLER("semop", ipc_semop_out
, default_in
),
440 const struct calls ipc_calls
= {
444 .count
= COUNT(ipc_map
)